1 UN Votes Analysis

1.1 options & settings

chunk options

CSS for scrollable output & Header colors

Turning scientific / Exponential numbers off

options(scipen = 999)

1.2 Source

David Robinson tidytuesday: https://www.youtube.com/watch?v=2RadZrpzTaA

1.3 Loading libs

library(tidyverse)
library(ggthemes)
library(tidytuesdayR)
library(tidytext)
library(scales)
library(lubridate)
library(glue)
library(ggtext)
library(widyr)
library(countrycode)
library(factoextra)
library(ggstream)
library(wesanderson)  # color pallete

1.4 Creating & setting custom theme


theme_viny_bright <- function(){
  
  library(ggthemes)
  
  ggthemes::theme_fivethirtyeight() %+replace%
  
  theme(
    axis.title = element_text(size = 10, face = "bold"),
    axis.text = element_text(size = 9),
    legend.text = element_text(size = 9),
    panel.background = element_rect(fill = "white"),
    plot.background = element_rect(fill = "white"),
    strip.background = element_blank(),
    legend.background = element_rect(fill = NA),
    legend.key = element_rect(fill = NA),
    legend.position = "right",
    legend.direction = "vertical",
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold",
                              family = "serif", margin=margin(0,0,15,0)),
    plot.subtitle = element_text(hjust = 0.5,face = "plain", family = "serif", size = 9),
    plot.caption = element_text(hjust = 1,  size = 8)
      )
  }

theme_set(theme_viny_bright())

1.5 Load Data

tt <- tt_load("2021-03-23")

    Downloading file 1 of 3: `unvotes.csv`
    Downloading file 2 of 3: `roll_calls.csv`
    Downloading file 3 of 3: `issues.csv`
tt
unvotes <- tt$unvotes

head(unvotes)
unvotes %>% 
  mutate_all(as.factor) %>% 
  summary()
      rcid               country        country_code         vote       
 5181   :   193   Canada     :  6176   CA     :  6176   abstain:110893  
 5249   :   193   Denmark    :  6170   DK     :  6170   no     : 65500  
 5313   :   193   Netherlands:  6170   NL     :  6170   yes    :693544  
 5394   :   193   Australia  :  6166   AU     :  6166                   
 5549   :   193   Norway     :  6162   NO     :  6162                   
 4979   :   192   Belgium    :  6161   (Other):831195                   
 (Other):868780   (Other)    :832932   NA's   :  7898                   
unvotes %>% 
  mutate_all(as.factor) %>% 
  group_by(country, vote) %>% 
  summarise(count = n()) %>%
  mutate(pct = count/sum(count)) %>% 
  ungroup() %>%
  filter(country == "India")

1.5.1 top bottom countries by vote type

unvotes %>% 
  mutate_all(as.factor) %>% 
  group_by(country, vote) %>% 
  summarise(count = n(), .groups = "drop_last") %>%
  mutate(pct = count/sum(count)) %>% 
  
  group_by(vote) %>%
  slice_max(pct, n = 10) %>% 
  mutate(country = str_wrap(country, width = 20)) %>% 
  
  ggplot(aes(x = pct, y = tidytext::reorder_within(country, by = pct, 
                                            within = vote))) +
  geom_col() +
  facet_wrap(~vote, scales = "free_y") +
  scale_y_reordered() +
  scale_x_continuous(labels = percent) +
  theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "top 10 countries by vote type",
       y = "", x = "percentage of vote type",
       caption = "created by ViSa")

unvotes %>% 
  mutate_all(as.factor) %>% 
  group_by(country, vote) %>% 
  summarise(count = n(), .groups = "drop_last") %>%
  mutate(pct = count/sum(count)) %>% 
  
  group_by(vote) %>%
  arrange(desc(pct)) %>% 
  slice(c(1:10, (n() - 10):n() )) %>%  # this selects both top & bottom 10
  mutate(country = str_wrap(country, width = 20)) %>% 
  
  ggplot(aes(x = pct, y = tidytext::reorder_within(country, by = pct, 
                                            within = vote))) +
  geom_point() +
  facet_wrap(~vote, scales = "free_y") +
  scale_y_reordered() +
  scale_x_continuous(labels = percent) +
  theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "top 10 & bottom 10 countries by each vote type",
       y = "", x = "percentage of vote type",
       caption = "created by ViSa")

unvotes %>% 
  mutate_all(as.factor) %>% 
  group_by(country) %>% 
  mutate(total_votes  = n()) %>%
  
  group_by(country, vote) %>% 
  summarise(count = n(), .groups = "drop_last",
            total_votes = first(total_votes)) %>%
  mutate(pct = count/sum(count)) %>% 
  
  group_by(vote) %>%
  arrange(desc(pct)) %>% 
  slice(c(1:10, (n() - 10):n() )) %>%  # this selects both top & bottom 10
  mutate(country = str_wrap(country, width = 20)) %>% 
  
  ggplot(aes(x = pct, 
             y = tidytext::reorder_within(country, by = pct, within = vote))) +
  geom_point(aes(size = total_votes)) +
  facet_wrap(~vote, scales = "free_y") +
  scale_y_reordered() +
  scale_x_continuous(labels = percent) +
  theme(axis.text.x = element_text(angle = 90), legend.position = "none") +
  labs(title = "top 10 & bottom 10 countries by each vote type",
       y = "", x = "percentage of vote type",
       caption = "created by ViSa")

unvotes <- unvotes %>% 
  mutate(vote_number = match(vote, c("no","abstain","yes")) -2)

unvotes

saving object for flexdasbhoard

flex_topbottom <- unvotes %>% 
  mutate_all(as.factor) %>% 
  group_by(country) %>% 
  mutate(total_votes  = n()) %>%
  
  group_by(country, vote) %>% 
  summarise(count = n(), .groups = "drop_last",
            total_votes = first(total_votes)) %>%
  mutate(pct = count/sum(count),
         country = str_wrap(country, width = 20)) %>% 
  
  group_by(vote) %>%
  arrange(desc(pct)) 
  
flex_topbottom %>%   
  slice(c(1:10, (n() - 10):n() )) %>%  # this selects both top & bottom 10
  
  ggplot(aes(x = pct, 
             y = tidytext::reorder_within(country, by = pct, within = vote))) +
  geom_point(aes(size = total_votes)) +
  facet_wrap(~vote, scales = "free_y") +
  scale_y_reordered() +
  scale_x_continuous(labels = percent) +
  theme(axis.text.x = element_text(angle = 90), legend.position = "none") +
  labs(title = "top 10 & bottom 10 countries by each vote type",
       y = "", x = "percentage of vote type",
       caption = "created by ViSa")

unvotes %>% 
  count(vote, vote_number)
by_country <- unvotes %>% 
  group_by(country) %>% 
  summarise(n_votes = n(),
            n_yes = sum(vote == "yes"),
            pct_yes = n_yes / n_votes) %>% 
  arrange(desc(pct_yes)) %>% 
  filter(n_votes >= 100)

by_country

1.5.2 fn summarize_votes()

summarize_votes <- function(df, min_votes = 10){
  df %>%  
  summarise(n_votes = n(),
            n_yes = sum(vote == "yes"),
            pct_yes = n_yes / n_votes) %>% 
  arrange(desc(pct_yes)) %>% 
  filter(n_votes >= min_votes)
}
by_country <- unvotes %>% 
  group_by(country) %>% 
  summarize_votes()

by_country

1.5.3 top bottom for yes votes

by_country %>%
  mutate(country = fct_reorder(country, pct_yes)) %>% 
  slice(c(1:10, (n() - 10):n() )) %>% 
  
  ggplot(aes(x = pct_yes, y = country)) +
  geom_point(aes(size = n_votes)) +
  scale_x_continuous(labels = percent) +
  labs(title = "Top & bottom countries with % of yes votes in UN",
       caption = "created by ViSa")

1.5.4 Least yes votes

by_country %>%
  mutate(country = fct_reorder(country, pct_yes)) %>% 
  slice_min(pct_yes, n = 20) %>% 
  
  ggplot(aes(x = pct_yes, y = country)) +
  geom_point(aes(size = n_votes)) +
  scale_x_continuous(labels = percent) +
  labs(title = "Countries with least % of yes votes in UN",
       y = "",
       caption = "created by ViSa")

1.5.5 roll_calls df

tt$roll_calls
unvotes <- unvotes %>% 
  left_join(tt$roll_calls %>% 
              select(rcid, date, amend), by = "rcid") 

unvotes
by_year <- unvotes %>% 
  group_by(year = year(date)) %>% 
  summarize_votes()

by_year
by_year %>% 
  ggplot(aes(x = year, y = pct_yes)) +
  geom_line( size = .9) +
  scale_y_continuous(labels = percent) +
  expand_limits(y = 0)

by_country_year <- unvotes %>% 
  group_by(year = year(date), 
           country) %>% 
  summarize_votes()

by_country_year
by_country_year %>% 
  filter(country %in% c("United States", "Canada", "Mali")) %>% 
  mutate(country = fct_reorder(country, pct_yes)) %>% 
  
  ggplot(aes(x = year, y = pct_yes, col = country)) +
  geom_line(size = 0.9) +
  scale_y_continuous(labels = percent) +
  scale_color_discrete(guide = guide_legend(reverse = TRUE)) +
  expand_limits(y = 0) +
  labs(title = "% yes by countries over the years",
       caption = "created by ViSa")

country_yes_line <- function(filter_list = c("India")){
    by_country_year %>% 
    filter(country %in% filter_list) %>% 
    mutate(country = fct_reorder(country, pct_yes)) %>% 
    
    ggplot(aes(x = year, y = pct_yes, col = country)) +
    geom_line(size = 0.9) +
    scale_y_continuous(labels = percent) +
    # scale_color_discrete(guide = guide_legend(reverse = TRUE)) +
    expand_limits(y = 0)+
    labs(title = "% yes votes by countries over the years",
       caption = "created by ViSa")
}
country_yes_line(filter_list = c("India", "Russia", "United States", "China"))

country_yes_line_facet <- function(filter_list = c("India")){
    by_country_year %>% 
    filter(country %in% filter_list) %>% 
    mutate(country = fct_reorder(country, pct_yes)) %>% 
    
    ggplot(aes(x = year, y = pct_yes, col = country)) +
    geom_line(size = 0.9, show.legend = FALSE) +
    scale_y_continuous(labels = percent) +
    # scale_color_discrete(guide = guide_legend(reverse = TRUE)) +
    expand_limits(y = 0)+
    facet_wrap(~country) +
    labs(title = "% yes by countries over the years",
       caption = "created by ViSa")
}
country_yes_line_facet(c("India","Russia","China","France","Pakistan","Sweden"))

country_yes_line_facet(c("India","Russia","France","Germany","United Kingdom","Turkey"))

From above charts lot of countries is close to 75% yes_vote now and this happened from 1990’s. Some European & Western countries goes lower than 75% which are mostly NATO allies.

1.5.6 Overall Countries avg

by_country_year <- unvotes %>% 
  bind_rows(unvotes %>% mutate(country = "Overall")) %>% 
  
  group_by(year = year(date),
           country) %>% 
  summarize_votes()
  
by_country_year %>%  
  filter(country == "Overall")
country_yes_line <- function(filter_list = c("India")){
    by_country_year %>% 
    filter(country %in% filter_list) %>% 
    mutate(country = fct_reorder(country, pct_yes)) %>% 
    
    ggplot(aes(x = year, y = pct_yes)) +
    geom_line(data = by_year, lty = 1, size = 1.8, alpha = 0.3) +
    geom_line(aes(col = country), size = 0.9) +
    scale_y_continuous(labels = percent) +
  # scale_color_discrete(guide = guide_legend(reverse = TRUE)) +
    expand_limits(y = 0)+
    labs(title = "% yes by countries over the years with world average",
       caption = "created by ViSa") +
    theme(legend.position = "top",
          legend.direction = "horizontal")
}
country_yes_line(filter_list = c("India", "Russia", "United States", "China"))

country_list <- unvotes %>% 
  distinct(country) %>% 
  pull()

country_list
  [1] "United States"                    "Canada"                          
  [3] "Cuba"                             "Haiti"                           
  [5] "Dominican Republic"               "Mexico"                          
  [7] "Guatemala"                        "Honduras"                        
  [9] "El Salvador"                      "Nicaragua"                       
 [11] "Costa Rica"                       "Panama"                          
 [13] "Colombia"                         "Venezuela"                       
 [15] "Ecuador"                          "Peru"                            
 [17] "Brazil"                           "Bolivia"                         
 [19] "Paraguay"                         "Chile"                           
 [21] "Argentina"                        "Uruguay"                         
 [23] "United Kingdom"                   "Netherlands"                     
 [25] "Belgium"                          "Luxembourg"                      
 [27] "France"                           "Poland"                          
 [29] "Czechoslovakia"                   "Yugoslavia"                      
 [31] "Greece"                           "Russia"                          
 [33] "Ukraine"                          "Belarus"                         
 [35] "Norway"                           "Denmark"                         
 [37] "Liberia"                          "Ethiopia"                        
 [39] "South Africa"                     "Iran"                            
 [41] "Turkey"                           "Iraq"                            
 [43] "Egypt"                            "Syria"                           
 [45] "Lebanon"                          "Saudi Arabia"                    
 [47] "Taiwan"                           "India"                           
 [49] "Philippines"                      "Australia"                       
 [51] "New Zealand"                      "Sweden"                          
 [53] "Iceland"                          "Afghanistan"                     
 [55] "Thailand"                         "Yemen Arab Republic"             
 [57] "Pakistan"                         "Myanmar (Burma)"                 
 [59] "Israel"                           "Indonesia"                       
 [61] "Hungary"                          "Jordan"                          
 [63] "Sri Lanka"                        "Spain"                           
 [65] "Romania"                          "Ireland"                         
 [67] "Portugal"                         "Austria"                         
 [69] "Italy"                            "Albania"                         
 [71] "Bulgaria"                         "Finland"                         
 [73] "Libya"                            "Nepal"                           
 [75] "Cambodia"                         "Laos"                            
 [77] "Sudan"                            "Morocco"                         
 [79] "Tunisia"                          "Japan"                           
 [81] "Ghana"                            "Malaysia"                        
 [83] "Guinea"                           "Cyprus"                          
 [85] "Mali"                             "Senegal"                         
 [87] "Benin"                            "Niger"                           
 [89] "Côte d’Ivoire"                    "Burkina Faso"                    
 [91] "Togo"                             "Cameroon"                        
 [93] "Gabon"                            "Central African Republic"        
 [95] "Chad"                             "Congo - Brazzaville"             
 [97] "Madagascar"                       "Somalia"                         
 [99] "Nigeria"                          "Congo - Kinshasa"                
[101] "Sierra Leone"                     "Mongolia"                        
[103] "Mauritania"                       "Tanzania"                        
[105] "Jamaica"                          "Burundi"                         
[107] "Rwanda"                           "Trinidad & Tobago"               
[109] "Algeria"                          "Uganda"                          
[111] "Kuwait"                           "Kenya"                           
[113] "Zanzibar"                         "Malta"                           
[115] "Zambia"                           "Malawi"                          
[117] "Maldives"                         "Singapore"                       
[119] "Gambia"                           "Guyana"                          
[121] "Lesotho"                          "Botswana"                        
[123] "Barbados"                         "Yemen People's Republic"         
[125] "Mauritius"                        "Equatorial Guinea"               
[127] "Eswatini"                         "Fiji"                            
[129] "Bhutan"                           "Bahrain"                         
[131] "Qatar"                            "Oman"                            
[133] "China"                            "United Arab Emirates"            
[135] "Federal Republic of Germany"      "German Democratic Republic"      
[137] "Bahamas"                          "Bangladesh"                      
[139] "Grenada"                          "Guinea-Bissau"                   
[141] "Cape Verde"                       "São Tomé & Príncipe"             
[143] "Mozambique"                       "Comoros"                         
[145] "Papua New Guinea"                 "Suriname"                        
[147] "Angola"                           "Djibouti"                        
[149] "Vietnam"                          "Samoa"                           
[151] "Seychelles"                       "Solomon Islands"                 
[153] "St. Lucia"                        "Zimbabwe"                        
[155] "St. Vincent & Grenadines"         "Vanuatu"                         
[157] "Belize"                           "Antigua & Barbuda"               
[159] "Dominica"                         "St. Kitts & Nevis"               
[161] "Brunei"                           "Liechtenstein"                   
[163] "Namibia"                          "Germany"                         
[165] "Estonia"                          "Latvia"                          
[167] "Lithuania"                        "Yemen"                           
[169] "North Korea"                      "South Korea"                     
[171] "Micronesia (Federated States of)" "Marshall Islands"                
[173] "San Marino"                       "Bosnia & Herzegovina"            
[175] "Armenia"                          "Azerbaijan"                      
[177] "Croatia"                          "Slovenia"                        
[179] "Moldova"                          "Turkmenistan"                    
[181] "Kyrgyzstan"                       "Kazakhstan"                      
[183] "Tajikistan"                       "Monaco"                          
[185] "Andorra"                          "Czechia"                         
[187] "Slovakia"                         "North Macedonia"                 
[189] "Eritrea"                          "Georgia"                         
[191] "Uzbekistan"                       "Palau"                           
[193] "Tonga"                            "Nauru"                           
[195] "Kiribati"                         "Tuvalu"                          
[197] "Switzerland"                      "Timor-Leste"                     
[199] "Montenegro"                       "South Sudan"                     

1.6 World Map

map_data("world") %>%
  filter(region != "Antarctica") %>% 
  
  ggplot(aes(x = long, y = lat, group = group)) +
  geom_polygon() +
  theme_map()

1.6.1 fn summarize_votes()

summarize_votes <- function(df, min_votes = 10){
  df %>%  
  summarise(n_votes = n(),
            n_yes = sum(vote == "yes"),
            pct_yes = n_yes / n_votes,
            .groups = "drop") %>% 
  arrange(desc(pct_yes)) %>% 
  filter(n_votes >= min_votes)
}
by_country <- unvotes %>% 
  group_by(country, country_code) %>% 
  summarize_votes()

by_country
by_country_year <- unvotes %>% 
  group_by(year = year(date), 
           country,
           country_code) %>% 
  summarize_votes()

by_country_year

1.6.2 world map

library(fuzzyjoin)
world_data <- map_data("world") %>% 
  filter(region != "Antarctica") %>%
  as_tibble() %>% 
  fuzzyjoin::regex_left_join(maps::iso3166 %>% 
                               select(mapname, country_code = a2),
                             c(region = "mapname"))

world_data
world_data %>%
  left_join(by_country, by = "country_code") %>% 
  
  ggplot(aes(x = long, y = lat, group = group, fill = pct_yes)) +
  geom_polygon() +
  theme_map() +
  scale_fill_gradient2(low = "red", high = "blue", 
                       midpoint = .6, labels = percent) +
  labs(fill = "% yes vote",
       caption = "created by ViSa")

1.7 by continet

library(countrycode)
unvotes %>% 
  mutate(continent = countrycode(country_code, "iso2c", "continent")) %>% 
  group_by(continent, year = year(date)) %>% 
  summarize_votes() %>% 
  filter(!is.na(continent)) %>% 
  
  mutate(country = fct_reorder(continent, pct_yes)) %>% 
  
  ggplot(aes(x = year, y = pct_yes)) +
  geom_line(data = by_year, lty = 1, size = 1.8, alpha = 0.3) +
  geom_line(aes(col = continent), size = 0.9) +
  scale_y_continuous(labels = percent) +
  scale_color_discrete(guide = guide_legend(reverse = TRUE)) +
  expand_limits(y = 0)+
  labs(title = "% yes by continents over the years with world average",
       caption = "created by ViSa")

1.8 gdp from WDI

library(WDI)
country_incomes <- WDI(indicator = c(gdp_per_capita = "NY.GDP.PCAP.PP.KD",
                  pop = "SP.POP.TOTL"),
    start = 2019, end = 2019, extra = TRUE) %>% 
  as_tibble() %>% 
  select(country_code = iso2c, income, gdp_per_capita, pop) %>% 
  filter(!is.na(income)) %>% 
  mutate(income = fct_relevel(income, "Low income", "Lower middle income", "Upper middle income"))

country_incomes
plot_by <- function(tbl, category){
    tbl %>%
    filter(!is.na({{category}})) %>% 
    mutate(category = fct_reorder({{category}}, pct_yes)) %>% 
    
    ggplot(aes(x = year, y = pct_yes)) +
    # geom_line(data = by_year, lty = 1, size = 1.8, alpha = 0.3) +
    geom_line(aes(col = {{category}}), size = 0.9) +
    scale_y_continuous(labels = percent) +
    scale_color_discrete(guide = guide_legend(reverse = TRUE)) +
    expand_limits(y = 0)+
    labs(title = "% yes by countries over the years with world average",
       caption = "created by ViSa")
}
unvotes %>% 
  inner_join(country_incomes, by = "country_code") %>% 
  group_by(income,
           year = year(date)) %>% 
  summarize_votes() %>% 
  plot_by(income)

1.9 Correlation bw countries

unvotes %>% 
  filter(country %in% c("India","Russia")) %>% 
  select(rcid, country, vote_number) %>% 
  spread(country, vote_number, fill = 0)
unvotes %>% 
  filter(country %in% c("India","Canada")) %>% 
  select(rcid, country, vote_number) %>% 
  spread(country, vote_number, fill = 0) %>% 
  summarize(correlation = cor(.[[2]],.[[3]]))
corr_fn <- function(countries_sel = c("India", "United States")){
  unvotes %>% 
  filter(country %in% countries_sel) %>% 
  select(rcid, country, vote_number) %>% 
  spread(country, vote_number, fill = 0) %>% 
  summarize(correlation = cor(.[[2]],.[[3]]))
}
corr_fn(c("India","Pakistan"))

1.9.1 widyr pairwise corr

library(widyr)
unvotes %>% 
  pairwise_cor(item = country, feature =  rcid, value =  vote_number, sort = TRUE)
library(tidygraph)
library(ggraph)

tidygraph & ggraph from: https://youtu.be/mApnx5NJwQA?t=862

unvotes %>% 
  pairwise_cor(item = country, feature =  rcid, 
               value =  vote_number, sort = TRUE) %>% 
  filter(item1 == "India")
corr_tbl <- unvotes %>% 
  pairwise_cor(item = country, feature =  rcid, 
               value =  vote_number, sort = TRUE) %>% 
  # filter(item1 == "India") %>% 
  
  left_join(y = (unvotes %>% 
                  mutate(continent = countrycode(country_code, "iso2c", "continent")) %>% 
                  select(country, continent) %>% 
                  distinct()),
            by = c("item2" = "country")) %>% 
  rename(continent_item2 = continent)

corr_tbl
corr_tbl %>% 
  filter(item1 == "India",
         !is.na(continent_item2)) %>% 
  arrange(desc(correlation)) %>% 
  slice(c(1:15, (n()- 0:15) )) %>% 
  mutate(item2 = str_wrap(item2, width = 25)) %>% 
  
  ggplot(aes(x = correlation, 
             y = reorder_within(item2, by = correlation, within = continent_item2), 
             col = continent_item2)) +
  geom_point(show.legend = FALSE) +
  geom_vline(xintercept = 0, lty = 2, size = 0.9, col = "tomato") +
  facet_wrap(~continent_item2, scales = "free_y") +
  scale_y_reordered() +
  labs(title = "Top & bottom correlated countries in voting in UN to India",
       y = "",
       caption = "created by ViSa") +
   theme(panel.grid.major.x = element_blank())

1.9.2 correlation of countries

top_corr_countries_with <- function(country_selected = "India", top_n_bottom = 15){
  corr_tbl %>% 
  filter(item1 == country_selected,
         !is.na(continent_item2)) %>% 
  arrange(desc(correlation)) %>% 
  slice(c(1:top_n_bottom, (n()- 0:top_n_bottom) )) %>% 
  mutate(item2 = str_wrap(item2, width = 25)) %>% 
  
  ggplot(aes(x = correlation, 
             y = reorder_within(item2, by = correlation, within = continent_item2),
             col = correlation > 0)) +
  geom_point() +
  geom_errorbarh(height = 0, aes(xmin = correlation, xmax = 0)) +
  geom_vline(xintercept = 0, lty = 2, size = 0.9, col = "midnightblue") +
  facet_wrap(~continent_item2, scales = "free_y") +
  scale_y_reordered() +
  expand_limits(x = 0.8) +
  labs(title = glue("Top & bottom correlated countries in voting in UN with <i>{country_selected}</i>"),
       y = "",
       caption = "created by ViSa") +
   theme(panel.grid.major.x = element_blank(),
         panel.grid.major.y = element_blank(),
         plot.title = ggtext::element_markdown(),
         legend.position = "none")
}

1.9.2.1 India

top_corr_countries_with(top_n_bottom = 20)

1.9.2.2 France

top_corr_countries_with("France", top_n_bottom = 20)

1.9.2.3 Pakistan

top_corr_countries_with("Pakistan", top_n_bottom = 20)

1.9.2.4 Russia

top_corr_countries_with("Russia", top_n_bottom = 20)

1.9.2.5 China

top_corr_countries_with("China", top_n_bottom = 20)

1.9.2.6 Australia

top_corr_countries_with("Australia", top_n_bottom = 20)

1.9.2.7 United Arab Emirates

top_corr_countries_with("United Arab Emirates", top_n_bottom = 20)

1.9.2.8 Saudi Arabia

top_corr_countries_with("Saudi Arabia", top_n_bottom = 20)

1.9.2.9 Israel

top_corr_countries_with("Israel", top_n_bottom = 20)

1.9.2.10 Turkey

top_corr_countries_with("Turkey", top_n_bottom = 20)

1.9.2.11 US

top_corr_countries_with("United States", top_n_bottom = 20)

1.9.3 Coorelation differences

corr_tbl %>% 
  group_by(country = item1) %>% 
  filter(!is.na(correlation)) %>% 
  mutate_if(is.character, as_factor) %>% #summary()
  summarise(median_corr = median(correlation),
            mean_corr = mean(correlation)) %>% 
  arrange(desc(median_corr))
corr_tbl <- corr_tbl %>% 
  select(-continent_item2) %>% 
  
  mutate(continent1 = countrycode(item1, "country.name", "continent"),
         continent2 = countrycode(item2, "country.name", "continent"))

corr_tbl

1.9.4 Intercontinent correlation

corr_tbl %>% 
  na.omit() %>%
  
  group_by(continent1, continent2) %>% 
  summarise(avg_corr = mean(correlation)) %>%
  arrange(desc(avg_corr))
intercontinent_corr <- corr_tbl %>% 
  na.omit() %>% 
  
  filter(continent1 == continent2) %>% 
  group_by(item1) %>% 
  summarise(avg_intercontinent_correlation = mean(correlation)) %>% 
  arrange(desc(avg_intercontinent_correlation))

intercontinent_corr

taiwan & israel have least corr which is in negative

library(plotly)
ggplotly(world_data %>%
  left_join((intercontinent_corr %>% 
               mutate(country_code = countrycode(item1, "country.name", "iso2c"))
             ), 
            by = c("country_code")) %>% 
  
  ggplot(aes(x = long, y = lat, group = group, 
             fill = avg_intercontinent_correlation, label = item1)) +
  geom_polygon() +
  theme_map() +
  scale_fill_gradient2(low = "red", high = "blue", 
                       midpoint = -0.1) +
  labs(fill = "avg intercontinent correlation",
       caption = "created by ViSa"))

both taiwan & israel are hard to be seen in map

1.10 text (issues)

tt$issues %>% 
  count(issue)
library(tidytext)
tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short) %>% 
  anti_join(stop_words, by = "word") %>% 
  count(word, sort = TRUE)
rc_words <- tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short) %>% 
  anti_join(stop_words, by = "word") %>% 
  select(rcid, word)

rc_words
unvotes %>% 
  inner_join(rc_words, by = "rcid")
unvotes %>% 
  inner_join(rc_words, by = "rcid") %>% 
  filter(country == "United States") %>% 
  group_by(word) %>% 
  summarize_votes(min_votes = 100) %>% 
  mutate(word = fct_reorder(word, pct_yes)) %>% 
  
  ggplot(aes(pct_yes, word)) +
  geom_point(aes(size = n_votes))+
  scale_x_continuous(labels = percent) 

1.10.1 yes vote words

words_yes_votes <- function(country_selected = "India", min_vote_limit = 100){
    unvotes %>% 
    inner_join(rc_words, by = "rcid") %>% 
    filter(country == country_selected) %>% 
    group_by(word) %>% 
    summarize_votes(min_votes = min_vote_limit) %>% 
    mutate(word = fct_reorder(word, pct_yes)) %>% 
    
    ggplot(aes(pct_yes, word)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent) +
    theme(plot.title = element_markdown()) +
    labs(title = glue("Most common words for yes votes by <i>{country_selected}</i>"))
}

1.10.1.1 India

words_yes_votes() 

1.10.1.2 Pakistan

words_yes_votes("Pakistan") 

1.10.1.3 Israel

words_yes_votes("Israel") 

1.10.2 pair country yes vote words

words_yes_votes_multi <- function(country_selected = c("India","Russia"), min_vote_limit = 100){
    unvotes %>% 
    inner_join(rc_words, by = "rcid") %>% 
    filter(country %in% country_selected) %>% 
    group_by(word, country) %>% 
    summarize_votes(min_votes = min_vote_limit) %>% 
    mutate(word = fct_reorder(word, pct_yes)) %>% 
    
    ggplot(aes(pct_yes, word, col = country)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent) +
    theme(plot.title = element_markdown()) #+
    # labs(title = glue("Most common words for yes votes by <i>{country_selected}</i>"))
}

1.10.2.1 Ind/Rus

words_yes_votes_multi()

1.10.2.2 Ind/Pak

words_yes_votes_multi(c("India","Pakistan") )

1.10.2.3 Ind/Chi

words_yes_votes_multi(c("India","China") )

1.10.3 Diff of yes votes

words_yes_votes_multi_diff <- function(country_selected = c("India","Russia"), min_vote_limit = 100){
    unvotes %>% 
    inner_join(rc_words, by = "rcid") %>% 
    filter(country %in% country_selected) %>% 
    group_by(word, country) %>% 
    summarize_votes(min_votes = min_vote_limit) %>% 
    mutate(word = fct_reorder(word, pct_yes, function(x) max(x) - min(x))) %>% 
    
    ggplot(aes(pct_yes, word, col = country)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent) +
    theme(plot.title = element_markdown()) #+
    # labs(title = glue("Most common words for yes votes by <i>{country_selected}</i>"))
}
words_yes_votes_multi_diff()

1.11 Ngrams

1.11.1 bi grams

tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short, token = "ngrams", n =2) %>% 
  count(word, sort = TRUE)
bi_grams <- tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short, token = "ngrams", n =2) %>% 
  na.omit() %>% 
  anti_join(stop_words, by = "word") %>% 
  select(rcid, word)

bi_grams
unvotes %>% 
    inner_join(bi_grams, by = "rcid") %>% 
    filter(country == "India") %>% 
    group_by(word) %>% 
    summarize_votes(min_votes = 20) %>% 
    mutate(word = fct_reorder(word, pct_yes)) %>% 
    
    ggplot(aes(pct_yes, word)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent)

1.11.2 yes vote bigrams

bigrams_yes_votes_multi <- function(country_selected = c("India","Russia"), min_vote_limit = 20)
  {
    unvotes %>% 
    inner_join(bi_grams, by = "rcid") %>% 
    filter(country %in% country_selected) %>% 
    group_by(word, country) %>% 
    summarize_votes(min_votes = min_vote_limit) %>% 
    mutate(word = fct_reorder(word, pct_yes)) %>% 
    
    ggplot(aes(pct_yes, word, col = country)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent) #+
    # theme(plot.title = element_markdown()) +
    # labs(title = glue("Most common bi grams for yes votes by <i>{country_selected}</i>"))
}

1.11.2.1 Ind/Rus

bigrams_yes_votes_multi()

1.11.2.2 Ind/Pak

bigrams_yes_votes_multi(c("India","Pakistan"))

1.11.2.3 Ind/Pak

bigrams_yes_votes_multi(c("India","United States"))

1.11.2.4 Ind/Fra

bigrams_yes_votes_multi(c("India","France"))

1.11.3 yes vote bigrams diff

bigrams_yes_votes_multi_diff <- function(country_selected = c("India","Russia"), min_vote_limit = 20)
  {
    unvotes %>% 
    inner_join(bi_grams, by = "rcid") %>% 
    filter(country %in% country_selected) %>% 
    group_by(word, country) %>% 
    summarize_votes(min_votes = min_vote_limit) %>% 
    mutate(word = fct_reorder(word, pct_yes, function(x) max(x) - min(x))) %>% 
    
    ggplot(aes(pct_yes, word, col = country)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent) #+
    # theme(plot.title = element_markdown()) +
    # labs(title = glue("Most common bi grams for yes votes by <i>{country_selected}</i>"))
}

1.11.3.1 Ind/Rus

bigrams_yes_votes_multi_diff()

1.11.3.2 Ind/Pak

bigrams_yes_votes_multi_diff(c("India","Pakistan"))

1.11.4 quad grams

tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short, token = "ngrams", n =4) %>% 
  na.omit() %>% 
  count(word, sort = TRUE)
quad_grams <- tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short, token = "ngrams", n =4) %>% 
  na.omit() %>% 
  anti_join(stop_words, by = "word") %>% 
  select(rcid, word)

quad_grams

1.11.5 yes vote quadgrams

quadgrams_yes_votes_multi <- function(country_selected = c("India","Russia"), min_vote_limit = 5)
  {
    unvotes %>% 
    inner_join(quad_grams, by = "rcid") %>% 
    filter(country %in% country_selected) %>% 
    group_by(word, country) %>% 
    summarize_votes(min_votes = min_vote_limit) %>% 
    mutate(word = fct_reorder(word, pct_yes)) %>% 
    
    ggplot(aes(pct_yes, word, col = country)) +
    geom_point(aes(size = n_votes))+
    scale_x_continuous(labels = percent) #+
    # theme(plot.title = element_markdown()) +
    # labs(title = glue("Most common bi grams for yes votes by <i>{country_selected}</i>"))
}

1.11.5.1 Ind/Rus

quadgrams_yes_votes_multi()

1.11.5.2 Ind/Can

quadgrams_yes_votes_multi(c("India","Canada"))

1.11.6 kashmir Searc

library(stringr)
tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short, token = "ngrams", n =2) %>% 
  na.omit() %>% 
  anti_join(stop_words, by = "word") %>% 
  select(rcid, word) %>% 
  filter(str_detect(word, regex("Kashmir", ignore_case = TRUE)))
tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short, token = "ngrams", n =2) %>% 
  na.omit() %>% 
  anti_join(stop_words, by = "word") %>% 
  select(rcid, word, descr) %>% 
  filter(str_detect(descr, regex("Kashmir", ignore_case = TRUE)))

1.12 PCA

1.12.1 on words

rc_words <- tt$roll_calls %>% 
  filter(!is.na(short)) %>% 
  unnest_tokens(word, short) %>% 
  anti_join(stop_words, by = "word") %>% 
  distinct(rcid, word) %>% 
  add_count(word, name = "word_count", sort = TRUE) %>%
  filter(word_count >= 100) %>% 
  select(rcid, word)

rc_words
by_country_word <- unvotes %>% 
  inner_join(rc_words, by = "rcid") %>% 
  group_by(word, country) %>% 
  summarize_votes(min_votes = 0)

by_country_word
by_country_word %>% 
  widely_svd( word, country, pct_yes)
by_country_word %>% 
  widely_svd(word, country, pct_yes) %>% 
  filter(dimension == 1) %>% 
  mutate(word = reorder_within(word, by = value, within = dimension)) %>% 
  top_n(30, abs(value)) %>%
  
  ggplot(aes(x = value, y = word )) +
  geom_col() +
  # facet_wrap(~dimension, scale = "free_y") + 
  scale_y_reordered()

by_country_word %>% 
  widely_svd(word, country, pct_yes) %>% 
  filter(dimension %in% c(1:6)) %>% 
  mutate(word = reorder_within(word, by = value, within = dimension)) %>% 
  top_n(90, abs(value)) %>%
  
  ggplot(aes(x = value, y = word, fill = value > 0)) +
  geom_col() +
  facet_wrap(~dimension, scale = "free_y") +
  scale_y_reordered() +
  theme(axis.text.x = element_text(angle = 90),
        legend.position = "none")

Restricting number of principal components to 5

by_country_word %>% 
  widely_svd(word, country, pct_yes, nv = 5) %>% 
  # filter(dimension %in% c(1:6)) %>% 
  mutate(word = reorder_within(word, by = value, within = dimension)) %>% 
  top_n(120, abs(value)) %>%
  
  ggplot(aes(x = value, y = word, fill = value > 0)) +
  geom_col() +
  facet_wrap(~dimension, scale = "free_y") +
  scale_y_reordered() +
  theme(axis.text.x = element_text(angle = 90),
        legend.position = "none")

1.12.2 On country

by_country_word %>% 
  widely_svd(country, word, pct_yes) %>% 
  filter(dimension %in% c(3)) %>% 
  mutate(country = reorder_within(country, by = value, within = dimension)) %>% 
  top_n(25, abs(value)) %>%
  
  ggplot(aes(x = value, y = country, fill = value > 0)) +
  geom_col() +
  # facet_wrap(~dimension, scale = "free_y") +
  scale_y_reordered() +
  theme(axis.text.x = element_text(angle = 90),
        legend.position = "none")

1.13 Clustering 15 comp

from: https://youtu.be/mApnx5NJwQA?t=982

clustering functions are not available in cran package

https://github.com/dgrtwo/widyr

# library(devtools)
# install_github("dgrtwo/widyr")
library(widyr)

widely_kmeans is not there is any version of widyr package.

library(factoextra)
svd_dimen15 <- by_country_word %>% 
  widely_svd(country, word, pct_yes, nv = 15)
svd_dimen15
sapply(svd_dimen15, function(x) sum(is.na(x))) 
  country dimension     value 
        0         0         0 
svd_dimen15_wide <-  pivot_wider(data = svd_dimen15, id_cols = country, names_from = dimension, values_from = value)

svd_dimen15_wide
svd_dimen15_wide <- as.data.frame(svd_dimen15_wide)
rownames(svd_dimen15_wide) <- svd_dimen15_wide$country
svd_dimen15_wide <- svd_dimen15_wide[,2:16]
svd_dimen15_wide
factoextra::fviz_nbclust(scale(svd_dimen15_wide), kmeans, method = "wss")

factoextra::fviz_nbclust(scale(svd_dimen15_wide), kmeans, method = "silhouette")

factoextra::fviz_nbclust(scale(svd_dimen15_wide), kmeans, method = "gap_stat")
Clustering k = 1,2,..., K.max (= 10): .. done
Bootstrapping, b = 1,2,..., B (= 100)  [one "." per sample]:
.................................................. 50 
.................................................. 100 

1.13.1 hierarchical cluster

hier5 <- hcut(svd_dimen15_wide, k = 5, stand = TRUE)
hier5

Call:
stats::hclust(d = x, method = hc_method)

Cluster method   : ward.D2 
Distance         : euclidean 
Number of objects: 200 
fviz_dend(hier5, rect = TRUE, cex = 0.5,
          k_colors = c("#00AFBB","#2E9FDF", "#E7B800", "#FC4E07", "#ff5733")
          )

1.13.2 kmeans

1.13.2.1 5 clust

set.seed(123)

km.res5 <- kmeans(svd_dimen15_wide, 5, nstart = 25)
km.res5
K-means clustering with 5 clusters of sizes 24, 5, 40, 27, 104

Cluster means:
            1           2           3           4            5            6
1 -0.05883850 -0.15975310  0.02716216 -0.04221911  0.015228648 -0.049397895
2 -0.06787841  0.04167016 -0.02902809 -0.09510712 -0.073549499 -0.116434435
3 -0.06741513  0.02375440  0.06525529  0.07434288 -0.039768751  0.001051916
4 -0.04911880 -0.07182883 -0.01853074  0.05268736 -0.007599480  0.103131394
5 -0.07728224  0.02616081 -0.02244492 -0.02061601  0.004283506 -0.004755643
              7            8            9           10           11           12
1 -0.0312774356  0.004835413  0.008346752  0.001524352  0.031526905  0.029606931
2  0.2250779070  0.298656113 -0.026532299  0.021728232 -0.002297519  0.028178317
3  0.0007964694 -0.003538696  0.012439233 -0.003694175 -0.015947688  0.032851438
4  0.0493076622  0.025998705  0.010950068 -0.019437228  0.004769787 -0.050350647
5 -0.0114965068 -0.017433816 -0.009033282  0.001226936 -0.004459528 -0.008699865
           13           14           15
1 -0.03529428  0.006831908  0.010852234
2 -0.01010099 -0.031485246  0.061317479
3 -0.04221760  0.006435989  0.009337899
4  0.03235324 -0.023208761 -0.015128591
5  0.01960858  0.001030353 -0.004318087

Clustering vector:
                          Angola                          Armenia 
                               5                                5 
                      Azerbaijan                          Bahrain 
                               5                                5 
                      Bangladesh             Bosnia & Herzegovina 
                               5                                5 
                          Brunei                       Cape Verde 
                               5                                5 
                         Comoros                         Djibouti 
                               5                                5 
                   Guinea-Bissau                          Namibia 
                               5                                5 
                     North Korea                            Qatar 
                               5                                5 
             São Tomé & Príncipe                       Seychelles 
                               5                                5 
            United Arab Emirates                          Vanuatu 
                               5                                3 
                         Vietnam                            Yemen 
                               5                                5 
                         Algeria                Antigua & Barbuda 
                               5                                3 
                           China              Congo - Brazzaville 
                               5                                5 
                        Dominica       German Democratic Republic 
                               3                                2 
                          Guinea                           Jordan 
                               5                                5 
                          Kuwait                            Libya 
                               5                                5 
                        Malaysia                             Mali 
                               5                                5 
                      Mauritania                           Monaco 
                               5                                1 
                        Mongolia                          Morocco 
                               5                                5 
                      Mozambique                             Oman 
                               5                                5 
                         Senegal                          Somalia 
                               5                                5 
               St. Kitts & Nevis                        St. Lucia 
                               3                                3 
        St. Vincent & Grenadines                            Sudan 
                               3                                5 
                        Suriname                       Tajikistan 
                               5                                1 
                        Tanzania                          Tunisia 
                               5                                5 
                          Uganda          Yemen People's Republic 
                               5                                2 
                          Zambia                         Zimbabwe 
                               5                                5 
                        Kiribati                            Nauru 
                               3                                3 
                          Taiwan                      Timor-Leste 
                               2                                1 
                           Tonga                     Turkmenistan 
                               3                                1 
                          Tuvalu      Federal Republic of Germany 
                               1                                4 
                         Andorra                           Belize 
                               1                                3 
                         Croatia                          Czechia 
                               1                                1 
                         Eritrea                          Estonia 
                               1                                1 
                         Georgia                          Germany 
                               1                                1 
                         Grenada                       Kazakhstan 
                               3                                1 
                      Kyrgyzstan                           Latvia 
                               1                                1 
                   Liechtenstein                        Lithuania 
                               4                                1 
                         Moldova                       Montenegro 
                               1                                1 
                 North Macedonia                         Slovakia 
                               1                                1 
                        Slovenia                      South Korea 
                               1                                4 
                     Switzerland                      South Sudan 
                               1                                4 
                           Benin                     Burkina Faso 
                               5                                5 
                          Guyana                          Jamaica 
                               5                                3 
                        Maldives                          Nigeria 
                               5                                5 
                       Singapore                        Sri Lanka 
                               5                                5 
             Yemen Arab Republic                           Bhutan 
                               2                                5 
               Equatorial Guinea                      Afghanistan 
                               3                                5 
                            Cuba                        Indonesia 
                               5                                5 
                            Iran                          Lebanon 
                               5                                5 
                        Pakistan                     Saudi Arabia 
                               5                                5 
                           Syria                           Turkey 
                               5                                5 
                         Lesotho                            Malta 
                               4                                5 
               Trinidad & Tobago                   Czechoslovakia 
                               5                                2 
                      San Marino                       Uzbekistan 
                               1                                1 
                       Mauritius                            Palau 
                               5                                3 
                           India                         Botswana 
                               5                                5 
                      Costa Rica                      El Salvador 
                               3                                3 
                            Peru                      Philippines 
                               5                                5 
                        Thailand                          Burundi 
                               5                                5 
                           Gabon                           Cyprus 
                               5                                5 
                        Ethiopia                            Niger 
                               5                                5 
                            Togo                         Barbados 
                               5                                3 
                         Liberia                     Sierra Leone 
                               3                                5 
                        Cambodia                         Eswatini 
                               5                                3 
                Congo - Kinshasa                           Gambia 
                               3                                5 
                         Bahamas                             Iraq 
                               3                                5 
                      Yugoslavia                 Papua New Guinea 
                               5                                3 
                           Egypt                         Honduras 
                               5                                3 
                           Kenya                         Colombia 
                               5                                5 
                          Mexico                       Madagascar 
                               5                                5 
                            Laos                             Fiji 
                               5                                3 
                           Nepal                         Cameroon 
                               5                                3 
                            Chad         Central African Republic 
                               5                                3 
                         Uruguay                  Solomon Islands 
                               3                                3 
                   Côte d’Ivoire                            Ghana 
                               3                                5 
                           Haiti                            Samoa 
                               3                                3 
                         Albania                          Ecuador 
                               5                                5 
              Dominican Republic                           Rwanda 
                               3                                5 
                 Myanmar (Burma)                        Guatemala 
                               5                                3 
                          Panama                          Bolivia 
                               3                                5 
                    South Africa                            Chile 
                               4                                3 
                       Nicaragua                        Venezuela 
                               5                                5 
                         Belarus                          Finland 
                               5                                4 
                          Brazil                          Ukraine 
                               5                                5 
                       Argentina                         Bulgaria 
                               5                                5 
                         Romania                           Russia 
                               5                                5 
                        Paraguay                           Malawi 
                               3                                4 
                         Hungary                 Marshall Islands 
                               5                                3 
                         Austria                           Poland 
                               4                                5 
                          Sweden                          Ireland 
                               4                                4 
                         Iceland                           Norway 
                               4                                4 
                     New Zealand                           Greece 
                               4                                4 
                         Denmark Micronesia (Federated States of) 
                               4                                3 
                           Spain                        Australia 
                               4                                4 
                           Japan                           Canada 
                               4                                4 
                     Netherlands                         Portugal 
                               4                                4 
                      Luxembourg                          Belgium 
                               4                                4 
                           Italy                   United Kingdom 
                               4                                4 
                          France                           Israel 
                               4                                3 
                   United States                         Zanzibar 
                               3                                5 

Within cluster sum of squares by cluster:
[1] 2.6730265 0.7970714 2.5388916 2.0926619 2.5761772
 (between_SS / total_SS =  23.8 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"      
km.res5$cluster
                          Angola                          Armenia 
                               5                                5 
                      Azerbaijan                          Bahrain 
                               5                                5 
                      Bangladesh             Bosnia & Herzegovina 
                               5                                5 
                          Brunei                       Cape Verde 
                               5                                5 
                         Comoros                         Djibouti 
                               5                                5 
                   Guinea-Bissau                          Namibia 
                               5                                5 
                     North Korea                            Qatar 
                               5                                5 
             São Tomé & Príncipe                       Seychelles 
                               5                                5 
            United Arab Emirates                          Vanuatu 
                               5                                3 
                         Vietnam                            Yemen 
                               5                                5 
                         Algeria                Antigua & Barbuda 
                               5                                3 
                           China              Congo - Brazzaville 
                               5                                5 
                        Dominica       German Democratic Republic 
                               3                                2 
                          Guinea                           Jordan 
                               5                                5 
                          Kuwait                            Libya 
                               5                                5 
                        Malaysia                             Mali 
                               5                                5 
                      Mauritania                           Monaco 
                               5                                1 
                        Mongolia                          Morocco 
                               5                                5 
                      Mozambique                             Oman 
                               5                                5 
                         Senegal                          Somalia 
                               5                                5 
               St. Kitts & Nevis                        St. Lucia 
                               3                                3 
        St. Vincent & Grenadines                            Sudan 
                               3                                5 
                        Suriname                       Tajikistan 
                               5                                1 
                        Tanzania                          Tunisia 
                               5                                5 
                          Uganda          Yemen People's Republic 
                               5                                2 
                          Zambia                         Zimbabwe 
                               5                                5 
                        Kiribati                            Nauru 
                               3                                3 
                          Taiwan                      Timor-Leste 
                               2                                1 
                           Tonga                     Turkmenistan 
                               3                                1 
                          Tuvalu      Federal Republic of Germany 
                               1                                4 
                         Andorra                           Belize 
                               1                                3 
                         Croatia                          Czechia 
                               1                                1 
                         Eritrea                          Estonia 
                               1                                1 
                         Georgia                          Germany 
                               1                                1 
                         Grenada                       Kazakhstan 
                               3                                1 
                      Kyrgyzstan                           Latvia 
                               1                                1 
                   Liechtenstein                        Lithuania 
                               4                                1 
                         Moldova                       Montenegro 
                               1                                1 
                 North Macedonia                         Slovakia 
                               1                                1 
                        Slovenia                      South Korea 
                               1                                4 
                     Switzerland                      South Sudan 
                               1                                4 
                           Benin                     Burkina Faso 
                               5                                5 
                          Guyana                          Jamaica 
                               5                                3 
                        Maldives                          Nigeria 
                               5                                5 
                       Singapore                        Sri Lanka 
                               5                                5 
             Yemen Arab Republic                           Bhutan 
                               2                                5 
               Equatorial Guinea                      Afghanistan 
                               3                                5 
                            Cuba                        Indonesia 
                               5                                5 
                            Iran                          Lebanon 
                               5                                5 
                        Pakistan                     Saudi Arabia 
                               5                                5 
                           Syria                           Turkey 
                               5                                5 
                         Lesotho                            Malta 
                               4                                5 
               Trinidad & Tobago                   Czechoslovakia 
                               5                                2 
                      San Marino                       Uzbekistan 
                               1                                1 
                       Mauritius                            Palau 
                               5                                3 
                           India                         Botswana 
                               5                                5 
                      Costa Rica                      El Salvador 
                               3                                3 
                            Peru                      Philippines 
                               5                                5 
                        Thailand                          Burundi 
                               5                                5 
                           Gabon                           Cyprus 
                               5                                5 
                        Ethiopia                            Niger 
                               5                                5 
                            Togo                         Barbados 
                               5                                3 
                         Liberia                     Sierra Leone 
                               3                                5 
                        Cambodia                         Eswatini 
                               5                                3 
                Congo - Kinshasa                           Gambia 
                               3                                5 
                         Bahamas                             Iraq 
                               3                                5 
                      Yugoslavia                 Papua New Guinea 
                               5                                3 
                           Egypt                         Honduras 
                               5                                3 
                           Kenya                         Colombia 
                               5                                5 
                          Mexico                       Madagascar 
                               5                                5 
                            Laos                             Fiji 
                               5                                3 
                           Nepal                         Cameroon 
                               5                                3 
                            Chad         Central African Republic 
                               5                                3 
                         Uruguay                  Solomon Islands 
                               3                                3 
                   Côte d’Ivoire                            Ghana 
                               3                                5 
                           Haiti                            Samoa 
                               3                                3 
                         Albania                          Ecuador 
                               5                                5 
              Dominican Republic                           Rwanda 
                               3                                5 
                 Myanmar (Burma)                        Guatemala 
                               5                                3 
                          Panama                          Bolivia 
                               3                                5 
                    South Africa                            Chile 
                               4                                3 
                       Nicaragua                        Venezuela 
                               5                                5 
                         Belarus                          Finland 
                               5                                4 
                          Brazil                          Ukraine 
                               5                                5 
                       Argentina                         Bulgaria 
                               5                                5 
                         Romania                           Russia 
                               5                                5 
                        Paraguay                           Malawi 
                               3                                4 
                         Hungary                 Marshall Islands 
                               5                                3 
                         Austria                           Poland 
                               4                                5 
                          Sweden                          Ireland 
                               4                                4 
                         Iceland                           Norway 
                               4                                4 
                     New Zealand                           Greece 
                               4                                4 
                         Denmark Micronesia (Federated States of) 
                               4                                3 
                           Spain                        Australia 
                               4                                4 
                           Japan                           Canada 
                               4                                4 
                     Netherlands                         Portugal 
                               4                                4 
                      Luxembourg                          Belgium 
                               4                                4 
                           Italy                   United Kingdom 
                               4                                4 
                          France                           Israel 
                               4                                3 
                   United States                         Zanzibar 
                               3                                5 
table(km.res5$cluster)

  1   2   3   4   5 
 24   5  40  27 104 
aggregate(svd_dimen15_wide, by = list(cluster = km.res5$cluster), mean)
svd_km5<- cbind(svd_dimen15_wide, cluster = km.res5$cluster)
svd_km5
fviz_cluster(km.res5, 
             data = svd_dimen15_wide,
             palette = c("#00AFBB","#2E9FDF", "#E7B800", "#FC4E07", "#ff5733"),
             main = "cluster plots",
             ggtheme = theme_clean()
             )

1.13.2.2 7 clust

set.seed(123)

km.res7 <- kmeans(svd_dimen15_wide, 7, nstart = 25)
km.res7
K-means clustering with 7 clusters of sizes 16, 8, 91, 23, 5, 33, 24

Cluster means:
            1             2           3            4           5           6
1 -0.06611477  0.0005389728 -0.04972262 -0.103441987 -0.12162064  0.02137175
2 -0.04586867 -0.0324567788  0.25340303  0.033963777 -0.11923419 -0.03912281
3 -0.07904042  0.0291390247 -0.01747947 -0.004146101  0.02619012 -0.01042357
4 -0.05848173 -0.1619430115  0.01837464 -0.038403946  0.01736273 -0.05071695
5 -0.06787841  0.0416701609 -0.02902809 -0.095107121 -0.07354950 -0.11643444
6 -0.07149645  0.0317438409  0.03178120  0.075601864 -0.01886258  0.01335675
7 -0.04793178 -0.0760845876 -0.02853858  0.057834862 -0.01022246  0.11632434
             7             8            9           10           11           12
1 -0.003850033 -0.0504648414  0.006000845 -0.051409429 -0.046476020 -0.040421140
2 -0.008280262 -0.0006645271 -0.036134815 -0.020231911 -0.007376369 -0.049480061
3 -0.012469197 -0.0104352864 -0.013043462  0.008272915  0.003808412 -0.004461497
4 -0.028873211  0.0019171313  0.019054570 -0.005675441  0.028345580  0.036817662
5  0.225077907  0.2986561128 -0.026532299  0.021728232 -0.002297519  0.028178317
6  0.007211103 -0.0026569244  0.023706000 -0.005451055 -0.009444211  0.034668749
7  0.046063646  0.0278874804  0.008897868  0.001400191 -0.004187335 -0.032580398
            13           14           15
1  0.007466883 -0.011948188 -0.022602237
2  0.076293735  0.037692783 -0.007305326
3  0.022440745  0.003060035 -0.004182515
4 -0.039044094 -0.006644028  0.008558640
5 -0.010100988 -0.031485246  0.061317479
6 -0.069676470  0.007881197  0.016666354
7  0.033436381 -0.024757326 -0.007072273

Clustering vector:
                          Angola                          Armenia 
                               3                                1 
                      Azerbaijan                          Bahrain 
                               1                                3 
                      Bangladesh             Bosnia & Herzegovina 
                               3                                1 
                          Brunei                       Cape Verde 
                               3                                3 
                         Comoros                         Djibouti 
                               3                                3 
                   Guinea-Bissau                          Namibia 
                               3                                3 
                     North Korea                            Qatar 
                               3                                3 
             São Tomé & Príncipe                       Seychelles 
                               3                                1 
            United Arab Emirates                          Vanuatu 
                               3                                3 
                         Vietnam                            Yemen 
                               3                                3 
                         Algeria                Antigua & Barbuda 
                               3                                6 
                           China              Congo - Brazzaville 
                               1                                3 
                        Dominica       German Democratic Republic 
                               6                                5 
                          Guinea                           Jordan 
                               3                                3 
                          Kuwait                            Libya 
                               3                                3 
                        Malaysia                             Mali 
                               3                                3 
                      Mauritania                           Monaco 
                               3                                4 
                        Mongolia                          Morocco 
                               1                                3 
                      Mozambique                             Oman 
                               3                                3 
                         Senegal                          Somalia 
                               3                                3 
               St. Kitts & Nevis                        St. Lucia 
                               6                                6 
        St. Vincent & Grenadines                            Sudan 
                               6                                3 
                        Suriname                       Tajikistan 
                               3                                4 
                        Tanzania                          Tunisia 
                               3                                3 
                          Uganda          Yemen People's Republic 
                               3                                5 
                          Zambia                         Zimbabwe 
                               3                                3 
                        Kiribati                            Nauru 
                               2                                2 
                          Taiwan                      Timor-Leste 
                               5                                4 
                           Tonga                     Turkmenistan 
                               2                                4 
                          Tuvalu      Federal Republic of Germany 
                               2                                7 
                         Andorra                           Belize 
                               4                                6 
                         Croatia                          Czechia 
                               4                                4 
                         Eritrea                          Estonia 
                               4                                4 
                         Georgia                          Germany 
                               4                                4 
                         Grenada                       Kazakhstan 
                               6                                4 
                      Kyrgyzstan                           Latvia 
                               4                                4 
                   Liechtenstein                        Lithuania 
                               7                                4 
                         Moldova                       Montenegro 
                               4                                4 
                 North Macedonia                         Slovakia 
                               4                                4 
                        Slovenia                      South Korea 
                               4                                1 
                     Switzerland                      South Sudan 
                               4                                2 
                           Benin                     Burkina Faso 
                               3                                3 
                          Guyana                          Jamaica 
                               3                                6 
                        Maldives                          Nigeria 
                               3                                3 
                       Singapore                        Sri Lanka 
                               3                                3 
             Yemen Arab Republic                           Bhutan 
                               5                                3 
               Equatorial Guinea                      Afghanistan 
                               6                                3 
                            Cuba                        Indonesia 
                               3                                3 
                            Iran                          Lebanon 
                               3                                3 
                        Pakistan                     Saudi Arabia 
                               3                                3 
                           Syria                           Turkey 
                               3                                1 
                         Lesotho                            Malta 
                               3                                3 
               Trinidad & Tobago                   Czechoslovakia 
                               3                                5 
                      San Marino                       Uzbekistan 
                               4                                4 
                       Mauritius                            Palau 
                               3                                2 
                           India                         Botswana 
                               3                                3 
                      Costa Rica                      El Salvador 
                               6                                6 
                            Peru                      Philippines 
                               3                                3 
                        Thailand                          Burundi 
                               3                                3 
                           Gabon                           Cyprus 
                               3                                3 
                        Ethiopia                            Niger 
                               3                                3 
                            Togo                         Barbados 
                               3                                6 
                         Liberia                     Sierra Leone 
                               6                                3 
                        Cambodia                         Eswatini 
                               3                                6 
                Congo - Kinshasa                           Gambia 
                               6                                3 
                         Bahamas                             Iraq 
                               6                                3 
                      Yugoslavia                 Papua New Guinea 
                               3                                6 
                           Egypt                         Honduras 
                               3                                6 
                           Kenya                         Colombia 
                               3                                3 
                          Mexico                       Madagascar 
                               3                                3 
                            Laos                             Fiji 
                               3                                6 
                           Nepal                         Cameroon 
                               3                                6 
                            Chad         Central African Republic 
                               3                                6 
                         Uruguay                  Solomon Islands 
                               6                                6 
                   Côte d’Ivoire                            Ghana 
                               6                                3 
                           Haiti                            Samoa 
                               6                                6 
                         Albania                          Ecuador 
                               1                                3 
              Dominican Republic                           Rwanda 
                               6                                3 
                 Myanmar (Burma)                        Guatemala 
                               3                                6 
                          Panama                          Bolivia 
                               6                                3 
                    South Africa                            Chile 
                               7                                6 
                       Nicaragua                        Venezuela 
                               3                                3 
                         Belarus                          Finland 
                               1                                7 
                          Brazil                          Ukraine 
                               3                                1 
                       Argentina                         Bulgaria 
                               3                                1 
                         Romania                           Russia 
                               1                                1 
                        Paraguay                           Malawi 
                               6                                7 
                         Hungary                 Marshall Islands 
                               1                                2 
                         Austria                           Poland 
                               7                                1 
                          Sweden                          Ireland 
                               7                                7 
                         Iceland                           Norway 
                               7                                7 
                     New Zealand                           Greece 
                               7                                7 
                         Denmark Micronesia (Federated States of) 
                               7                                2 
                           Spain                        Australia 
                               7                                7 
                           Japan                           Canada 
                               7                                7 
                     Netherlands                         Portugal 
                               7                                7 
                      Luxembourg                          Belgium 
                               7                                7 
                           Italy                   United Kingdom 
                               7                                7 
                          France                           Israel 
                               7                                6 
                   United States                         Zanzibar 
                               6                                3 

Within cluster sum of squares by cluster:
[1] 0.9107063 1.6223505 1.2851942 2.3711807 0.7970714 1.0286972 1.4396068
 (between_SS / total_SS =  32.5 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"      
km.res7$cluster
                          Angola                          Armenia 
                               3                                1 
                      Azerbaijan                          Bahrain 
                               1                                3 
                      Bangladesh             Bosnia & Herzegovina 
                               3                                1 
                          Brunei                       Cape Verde 
                               3                                3 
                         Comoros                         Djibouti 
                               3                                3 
                   Guinea-Bissau                          Namibia 
                               3                                3 
                     North Korea                            Qatar 
                               3                                3 
             São Tomé & Príncipe                       Seychelles 
                               3                                1 
            United Arab Emirates                          Vanuatu 
                               3                                3 
                         Vietnam                            Yemen 
                               3                                3 
                         Algeria                Antigua & Barbuda 
                               3                                6 
                           China              Congo - Brazzaville 
                               1                                3 
                        Dominica       German Democratic Republic 
                               6                                5 
                          Guinea                           Jordan 
                               3                                3 
                          Kuwait                            Libya 
                               3                                3 
                        Malaysia                             Mali 
                               3                                3 
                      Mauritania                           Monaco 
                               3                                4 
                        Mongolia                          Morocco 
                               1                                3 
                      Mozambique                             Oman 
                               3                                3 
                         Senegal                          Somalia 
                               3                                3 
               St. Kitts & Nevis                        St. Lucia 
                               6                                6 
        St. Vincent & Grenadines                            Sudan 
                               6                                3 
                        Suriname                       Tajikistan 
                               3                                4 
                        Tanzania                          Tunisia 
                               3                                3 
                          Uganda          Yemen People's Republic 
                               3                                5 
                          Zambia                         Zimbabwe 
                               3                                3 
                        Kiribati                            Nauru 
                               2                                2 
                          Taiwan                      Timor-Leste 
                               5                                4 
                           Tonga                     Turkmenistan 
                               2                                4 
                          Tuvalu      Federal Republic of Germany 
                               2                                7 
                         Andorra                           Belize 
                               4                                6 
                         Croatia                          Czechia 
                               4                                4 
                         Eritrea                          Estonia 
                               4                                4 
                         Georgia                          Germany 
                               4                                4 
                         Grenada                       Kazakhstan 
                               6                                4 
                      Kyrgyzstan                           Latvia 
                               4                                4 
                   Liechtenstein                        Lithuania 
                               7                                4 
                         Moldova                       Montenegro 
                               4                                4 
                 North Macedonia                         Slovakia 
                               4                                4 
                        Slovenia                      South Korea 
                               4                                1 
                     Switzerland                      South Sudan 
                               4                                2 
                           Benin                     Burkina Faso 
                               3                                3 
                          Guyana                          Jamaica 
                               3                                6 
                        Maldives                          Nigeria 
                               3                                3 
                       Singapore                        Sri Lanka 
                               3                                3 
             Yemen Arab Republic                           Bhutan 
                               5                                3 
               Equatorial Guinea                      Afghanistan 
                               6                                3 
                            Cuba                        Indonesia 
                               3                                3 
                            Iran                          Lebanon 
                               3                                3 
                        Pakistan                     Saudi Arabia 
                               3                                3 
                           Syria                           Turkey 
                               3                                1 
                         Lesotho                            Malta 
                               3                                3 
               Trinidad & Tobago                   Czechoslovakia 
                               3                                5 
                      San Marino                       Uzbekistan 
                               4                                4 
                       Mauritius                            Palau 
                               3                                2 
                           India                         Botswana 
                               3                                3 
                      Costa Rica                      El Salvador 
                               6                                6 
                            Peru                      Philippines 
                               3                                3 
                        Thailand                          Burundi 
                               3                                3 
                           Gabon                           Cyprus 
                               3                                3 
                        Ethiopia                            Niger 
                               3                                3 
                            Togo                         Barbados 
                               3                                6 
                         Liberia                     Sierra Leone 
                               6                                3 
                        Cambodia                         Eswatini 
                               3                                6 
                Congo - Kinshasa                           Gambia 
                               6                                3 
                         Bahamas                             Iraq 
                               6                                3 
                      Yugoslavia                 Papua New Guinea 
                               3                                6 
                           Egypt                         Honduras 
                               3                                6 
                           Kenya                         Colombia 
                               3                                3 
                          Mexico                       Madagascar 
                               3                                3 
                            Laos                             Fiji 
                               3                                6 
                           Nepal                         Cameroon 
                               3                                6 
                            Chad         Central African Republic 
                               3                                6 
                         Uruguay                  Solomon Islands 
                               6                                6 
                   Côte d’Ivoire                            Ghana 
                               6                                3 
                           Haiti                            Samoa 
                               6                                6 
                         Albania                          Ecuador 
                               1                                3 
              Dominican Republic                           Rwanda 
                               6                                3 
                 Myanmar (Burma)                        Guatemala 
                               3                                6 
                          Panama                          Bolivia 
                               6                                3 
                    South Africa                            Chile 
                               7                                6 
                       Nicaragua                        Venezuela 
                               3                                3 
                         Belarus                          Finland 
                               1                                7 
                          Brazil                          Ukraine 
                               3                                1 
                       Argentina                         Bulgaria 
                               3                                1 
                         Romania                           Russia 
                               1                                1 
                        Paraguay                           Malawi 
                               6                                7 
                         Hungary                 Marshall Islands 
                               1                                2 
                         Austria                           Poland 
                               7                                1 
                          Sweden                          Ireland 
                               7                                7 
                         Iceland                           Norway 
                               7                                7 
                     New Zealand                           Greece 
                               7                                7 
                         Denmark Micronesia (Federated States of) 
                               7                                2 
                           Spain                        Australia 
                               7                                7 
                           Japan                           Canada 
                               7                                7 
                     Netherlands                         Portugal 
                               7                                7 
                      Luxembourg                          Belgium 
                               7                                7 
                           Italy                   United Kingdom 
                               7                                7 
                          France                           Israel 
                               7                                6 
                   United States                         Zanzibar 
                               6                                3 
table(km.res7$cluster)

 1  2  3  4  5  6  7 
16  8 91 23  5 33 24 
aggregate(svd_dimen15_wide, by = list(cluster = km.res7$cluster), mean)
svd_km7<- cbind(svd_dimen15_wide, cluster = km.res7$cluster)
svd_km7
fviz_cluster(km.res7, 
             data = svd_dimen15_wide,
             palette = c("#00AFBB","#2E9FDF", "#E7B800", "#FC4E07", 
                         "#ff5733", "#33ff42", "#f333ff"),
             main = "cluster plots",
             ggtheme = theme_clean()
             )

1.14 Clustering all comp

svd_dimen_all <- by_country_word %>% 
  widely_svd(country, word, pct_yes)
svd_dimen_all
svd_dimen_all_wide <-  pivot_wider(data = svd_dimen_all, id_cols = country, names_from = dimension, values_from = value)

svd_dimen_all_wide
svd_dimen_all_wide <- as.data.frame(svd_dimen_all_wide)
rownames(svd_dimen_all_wide) <- svd_dimen_all_wide$country
svd_dimen_all_wide
svd_dimen_all_wide <- svd_dimen_all_wide[,2:30]
svd_dimen_all_wide
wss <- factoextra::fviz_nbclust(scale(svd_dimen_all_wide), kmeans, method = "wss")
wss

silhouette <- factoextra::fviz_nbclust(scale(svd_dimen_all_wide), kmeans, method = "silhouette")

silhouette

gap_stat <- factoextra::fviz_nbclust(scale(svd_dimen_all_wide), kmeans, method = "gap_stat")
Clustering k = 1,2,..., K.max (= 10): .. done
Bootstrapping, b = 1,2,..., B (= 100)  [one "." per sample]:
.................................................. 50 
.................................................. 100 
gap_stat

1.14.1 kmeans all

1.14.1.1 2 clust

set.seed(123)

km.res_all_2 <- kmeans(svd_dimen_all_wide, 2, nstart = 25)
km.res_all_2
K-means clustering with 2 clusters of sizes 6, 194

Cluster means:
            1           2            3            4           5            6
1 -0.06139325  0.02107797 -0.031731997 -0.071108429 0.061614167 -0.068858189
2 -0.06929547 -0.01041582  0.002436869  0.006134359 0.005067146  0.005038479
             7            8             9           10           11          12
1  0.206963898 -0.292065376  0.0282339387 -0.032867020 0.0221243746  0.04799433
2 -0.003605791  0.007194646 -0.0004681654  0.003077048 0.0004897412 -0.00199332
            13            14           15           16            17
1 -0.016700867 -0.0330012270  0.047456482  0.080158569 -0.0005939739
2  0.002199812 -0.0002963578 -0.001895586 -0.002759852 -0.0014781935
            18            19           20            21            22
1 0.0023536140 -0.0126201482  0.003607988 -0.0073441991 -0.0003078067
2 0.0004010253  0.0003282263 -0.001035063  0.0004940144  0.0008492005
              23            24           25            26             27
1 -0.00608619875 -0.0051930215 -0.025993852 -0.0244021009  0.01668698542
2  0.00005197066  0.0003507106 -0.000191068  0.0007040355 -0.00007176241
           28           29
1 -0.01400574  0.023086375
2 -0.00048371 -0.001122705

Clustering vector:
                          Angola                          Armenia 
                               2                                2 
                      Azerbaijan                          Bahrain 
                               2                                2 
                      Bangladesh             Bosnia & Herzegovina 
                               2                                2 
                          Brunei                       Cape Verde 
                               2                                2 
                         Comoros                         Djibouti 
                               2                                2 
                   Guinea-Bissau                          Namibia 
                               2                                2 
                     North Korea                            Qatar 
                               2                                2 
             São Tomé & Príncipe                       Seychelles 
                               2                                2 
            United Arab Emirates                          Vanuatu 
                               2                                2 
                         Vietnam                            Yemen 
                               2                                2 
                         Algeria                Antigua & Barbuda 
                               2                                2 
                           China              Congo - Brazzaville 
                               2                                2 
                        Dominica       German Democratic Republic 
                               2                                1 
                          Guinea                           Jordan 
                               2                                2 
                          Kuwait                            Libya 
                               2                                2 
                        Malaysia                             Mali 
                               2                                2 
                      Mauritania                           Monaco 
                               2                                2 
                        Mongolia                          Morocco 
                               2                                2 
                      Mozambique                             Oman 
                               2                                2 
                         Senegal                          Somalia 
                               2                                2 
               St. Kitts & Nevis                        St. Lucia 
                               2                                2 
        St. Vincent & Grenadines                            Sudan 
                               2                                2 
                        Suriname                       Tajikistan 
                               2                                2 
                        Tanzania                          Tunisia 
                               2                                2 
                          Uganda          Yemen People's Republic 
                               2                                1 
                          Zambia                         Zimbabwe 
                               2                                2 
                        Kiribati                            Nauru 
                               2                                2 
                          Taiwan                      Timor-Leste 
                               1                                2 
                           Tonga                     Turkmenistan 
                               2                                2 
                          Tuvalu      Federal Republic of Germany 
                               2                                1 
                         Andorra                           Belize 
                               2                                2 
                         Croatia                          Czechia 
                               2                                2 
                         Eritrea                          Estonia 
                               2                                2 
                         Georgia                          Germany 
                               2                                2 
                         Grenada                       Kazakhstan 
                               2                                2 
                      Kyrgyzstan                           Latvia 
                               2                                2 
                   Liechtenstein                        Lithuania 
                               2                                2 
                         Moldova                       Montenegro 
                               2                                2 
                 North Macedonia                         Slovakia 
                               2                                2 
                        Slovenia                      South Korea 
                               2                                2 
                     Switzerland                      South Sudan 
                               2                                2 
                           Benin                     Burkina Faso 
                               2                                2 
                          Guyana                          Jamaica 
                               2                                2 
                        Maldives                          Nigeria 
                               2                                2 
                       Singapore                        Sri Lanka 
                               2                                2 
             Yemen Arab Republic                           Bhutan 
                               1                                2 
               Equatorial Guinea                      Afghanistan 
                               2                                2 
                            Cuba                        Indonesia 
                               2                                2 
                            Iran                          Lebanon 
                               2                                2 
                        Pakistan                     Saudi Arabia 
                               2                                2 
                           Syria                           Turkey 
                               2                                2 
                         Lesotho                            Malta 
                               2                                2 
               Trinidad & Tobago                   Czechoslovakia 
                               2                                1 
                      San Marino                       Uzbekistan 
                               2                                2 
                       Mauritius                            Palau 
                               2                                2 
                           India                         Botswana 
                               2                                2 
                      Costa Rica                      El Salvador 
                               2                                2 
                            Peru                      Philippines 
                               2                                2 
                        Thailand                          Burundi 
                               2                                2 
                           Gabon                           Cyprus 
                               2                                2 
                        Ethiopia                            Niger 
                               2                                2 
                            Togo                         Barbados 
                               2                                2 
                         Liberia                     Sierra Leone 
                               2                                2 
                        Cambodia                         Eswatini 
                               2                                2 
                Congo - Kinshasa                           Gambia 
                               2                                2 
                         Bahamas                             Iraq 
                               2                                2 
                      Yugoslavia                 Papua New Guinea 
                               2                                2 
                           Egypt                         Honduras 
                               2                                2 
                           Kenya                         Colombia 
                               2                                2 
                          Mexico                       Madagascar 
                               2                                2 
                            Laos                             Fiji 
                               2                                2 
                           Nepal                         Cameroon 
                               2                                2 
                            Chad         Central African Republic 
                               2                                2 
                         Uruguay                  Solomon Islands 
                               2                                2 
                   Côte d’Ivoire                            Ghana 
                               2                                2 
                           Haiti                            Samoa 
                               2                                2 
                         Albania                          Ecuador 
                               2                                2 
              Dominican Republic                           Rwanda 
                               2                                2 
                 Myanmar (Burma)                        Guatemala 
                               2                                2 
                          Panama                          Bolivia 
                               2                                2 
                    South Africa                            Chile 
                               2                                2 
                       Nicaragua                        Venezuela 
                               2                                2 
                         Belarus                          Finland 
                               2                                2 
                          Brazil                          Ukraine 
                               2                                2 
                       Argentina                         Bulgaria 
                               2                                2 
                         Romania                           Russia 
                               2                                2 
                        Paraguay                           Malawi 
                               2                                2 
                         Hungary                 Marshall Islands 
                               2                                2 
                         Austria                           Poland 
                               2                                2 
                          Sweden                          Ireland 
                               2                                2 
                         Iceland                           Norway 
                               2                                2 
                     New Zealand                           Greece 
                               2                                2 
                         Denmark Micronesia (Federated States of) 
                               2                                2 
                           Spain                        Australia 
                               2                                2 
                           Japan                           Canada 
                               2                                2 
                     Netherlands                         Portugal 
                               2                                2 
                      Luxembourg                          Belgium 
                               2                                2 
                           Italy                   United Kingdom 
                               2                                2 
                          France                           Israel 
                               2                                2 
                   United States                         Zanzibar 
                               2                                2 

Within cluster sum of squares by cluster:
[1]  2.538819 24.485084
 (between_SS / total_SS =   3.5 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"      
km.res_all_2$cluster
                          Angola                          Armenia 
                               2                                2 
                      Azerbaijan                          Bahrain 
                               2                                2 
                      Bangladesh             Bosnia & Herzegovina 
                               2                                2 
                          Brunei                       Cape Verde 
                               2                                2 
                         Comoros                         Djibouti 
                               2                                2 
                   Guinea-Bissau                          Namibia 
                               2                                2 
                     North Korea                            Qatar 
                               2                                2 
             São Tomé & Príncipe                       Seychelles 
                               2                                2 
            United Arab Emirates                          Vanuatu 
                               2                                2 
                         Vietnam                            Yemen 
                               2                                2 
                         Algeria                Antigua & Barbuda 
                               2                                2 
                           China              Congo - Brazzaville 
                               2                                2 
                        Dominica       German Democratic Republic 
                               2                                1 
                          Guinea                           Jordan 
                               2                                2 
                          Kuwait                            Libya 
                               2                                2 
                        Malaysia                             Mali 
                               2                                2 
                      Mauritania                           Monaco 
                               2                                2 
                        Mongolia                          Morocco 
                               2                                2 
                      Mozambique                             Oman 
                               2                                2 
                         Senegal                          Somalia 
                               2                                2 
               St. Kitts & Nevis                        St. Lucia 
                               2                                2 
        St. Vincent & Grenadines                            Sudan 
                               2                                2 
                        Suriname                       Tajikistan 
                               2                                2 
                        Tanzania                          Tunisia 
                               2                                2 
                          Uganda          Yemen People's Republic 
                               2                                1 
                          Zambia                         Zimbabwe 
                               2                                2 
                        Kiribati                            Nauru 
                               2                                2 
                          Taiwan                      Timor-Leste 
                               1                                2 
                           Tonga                     Turkmenistan 
                               2                                2 
                          Tuvalu      Federal Republic of Germany 
                               2                                1 
                         Andorra                           Belize 
                               2                                2 
                         Croatia                          Czechia 
                               2                                2 
                         Eritrea                          Estonia 
                               2                                2 
                         Georgia                          Germany 
                               2                                2 
                         Grenada                       Kazakhstan 
                               2                                2 
                      Kyrgyzstan                           Latvia 
                               2                                2 
                   Liechtenstein                        Lithuania 
                               2                                2 
                         Moldova                       Montenegro 
                               2                                2 
                 North Macedonia                         Slovakia 
                               2                                2 
                        Slovenia                      South Korea 
                               2                                2 
                     Switzerland                      South Sudan 
                               2                                2 
                           Benin                     Burkina Faso 
                               2                                2 
                          Guyana                          Jamaica 
                               2                                2 
                        Maldives                          Nigeria 
                               2                                2 
                       Singapore                        Sri Lanka 
                               2                                2 
             Yemen Arab Republic                           Bhutan 
                               1                                2 
               Equatorial Guinea                      Afghanistan 
                               2                                2 
                            Cuba                        Indonesia 
                               2                                2 
                            Iran                          Lebanon 
                               2                                2 
                        Pakistan                     Saudi Arabia 
                               2                                2 
                           Syria                           Turkey 
                               2                                2 
                         Lesotho                            Malta 
                               2                                2 
               Trinidad & Tobago                   Czechoslovakia 
                               2                                1 
                      San Marino                       Uzbekistan 
                               2                                2 
                       Mauritius                            Palau 
                               2                                2 
                           India                         Botswana 
                               2                                2 
                      Costa Rica                      El Salvador 
                               2                                2 
                            Peru                      Philippines 
                               2                                2 
                        Thailand                          Burundi 
                               2                                2 
                           Gabon                           Cyprus 
                               2                                2 
                        Ethiopia                            Niger 
                               2                                2 
                            Togo                         Barbados 
                               2                                2 
                         Liberia                     Sierra Leone 
                               2                                2 
                        Cambodia                         Eswatini 
                               2                                2 
                Congo - Kinshasa                           Gambia 
                               2                                2 
                         Bahamas                             Iraq 
                               2                                2 
                      Yugoslavia                 Papua New Guinea 
                               2                                2 
                           Egypt                         Honduras 
                               2                                2 
                           Kenya                         Colombia 
                               2                                2 
                          Mexico                       Madagascar 
                               2                                2 
                            Laos                             Fiji 
                               2                                2 
                           Nepal                         Cameroon 
                               2                                2 
                            Chad         Central African Republic 
                               2                                2 
                         Uruguay                  Solomon Islands 
                               2                                2 
                   Côte d’Ivoire                            Ghana 
                               2                                2 
                           Haiti                            Samoa 
                               2                                2 
                         Albania                          Ecuador 
                               2                                2 
              Dominican Republic                           Rwanda 
                               2                                2 
                 Myanmar (Burma)                        Guatemala 
                               2                                2 
                          Panama                          Bolivia 
                               2                                2 
                    South Africa                            Chile 
                               2                                2 
                       Nicaragua                        Venezuela 
                               2                                2 
                         Belarus                          Finland 
                               2                                2 
                          Brazil                          Ukraine 
                               2                                2 
                       Argentina                         Bulgaria 
                               2                                2 
                         Romania                           Russia 
                               2                                2 
                        Paraguay                           Malawi 
                               2                                2 
                         Hungary                 Marshall Islands 
                               2                                2 
                         Austria                           Poland 
                               2                                2 
                          Sweden                          Ireland 
                               2                                2 
                         Iceland                           Norway 
                               2                                2 
                     New Zealand                           Greece 
                               2                                2 
                         Denmark Micronesia (Federated States of) 
                               2                                2 
                           Spain                        Australia 
                               2                                2 
                           Japan                           Canada 
                               2                                2 
                     Netherlands                         Portugal 
                               2                                2 
                      Luxembourg                          Belgium 
                               2                                2 
                           Italy                   United Kingdom 
                               2                                2 
                          France                           Israel 
                               2                                2 
                   United States                         Zanzibar 
                               2                                2 
table(km.res_all_2$cluster)

  1   2 
  6 194 
aggregate(svd_dimen_all_wide, by = list(cluster = km.res_all_2$cluster), mean)
svd_km_all_2<- cbind(svd_dimen_all_wide, cluster = km.res_all_2$cluster)
svd_km_all_2
fviz_cluster(km.res_all_2, 
             data = svd_dimen_all_wide,
             palette = c("#00AFBB","#E7B800"), # "#2E9FDF", "#FC4E07", "#ff5733"),
             main = "cluster plots",
             ggtheme = theme_clean()
             )

1.14.1.2 6 clust

set.seed(123)

km.res_all_6 <- kmeans(svd_dimen_all_wide, 6, nstart = 25)
km.res_all_6
K-means clustering with 6 clusters of sizes 17, 5, 89, 19, 58, 12

Cluster means:
            1            2            3            4           5            6
1 -0.06153182  0.010079120  0.018041323 -0.079446958  0.14466348  0.036944903
2 -0.06787841  0.041670161 -0.029028086 -0.095107121  0.07354950 -0.116434435
3 -0.07905462  0.028473118 -0.017447432 -0.004959457 -0.02648906 -0.008897402
4 -0.05322435 -0.170362010 -0.015443428  0.007344535  0.03183601 -0.080546873
5 -0.06215663 -0.009795446 -0.002399368  0.068518412  0.01886808  0.046775307
6 -0.06450331 -0.083582549  0.175517360 -0.090222779 -0.06800182  0.010643009
            7           8            9           10           11           12
1 -0.03717477  0.02271060 -0.003247939  0.049089561  0.039264628 -0.034010623
2  0.22507791 -0.29865611  0.026532299 -0.021728232  0.002297519  0.028178317
3 -0.01098023  0.01429689  0.014654362 -0.008679015 -0.004960538 -0.003531060
4 -0.01740719  0.01869446 -0.034700987 -0.045696574 -0.007593595 -0.002818792
5  0.01977140 -0.01251500 -0.016680765  0.007411617  0.012981166  0.010828505
6  0.01750648 -0.01259821  0.026974825  0.073721439 -0.051530973  0.006526593
           13           14            15           16           17           18
1  0.01381594 -0.022786086  0.0070141562 -0.004193696  0.010574437  0.009796145
2 -0.01010099 -0.031485244 -0.0613174476  0.077812941  0.043116153 -0.002420708
3  0.02248038  0.004676469  0.0023545846  0.012838770 -0.017097403 -0.007555227
4 -0.00608708  0.011276797 -0.0002718366  0.017044448  0.009588254 -0.035007813
5 -0.02608786 -0.004860531  0.0001799057 -0.026832707  0.016103113  0.013600405
6 -0.01915094 -0.004938769 -0.0092071578 -0.023535822 -0.023347342  0.040519156
             19            20           21           22           23
1  0.0006201514 -0.0284128427 -0.038348540 -0.022580277 -0.036727851
2  0.0002212013  0.0554714318 -0.038533704 -0.024724888  0.003942613
3 -0.0014538048 -0.0008028494 -0.007248286  0.003339062 -0.004933491
4  0.0154494501 -0.0029790538 -0.008443280  0.014073004 -0.013112443
5 -0.0023017511  0.0047351923  0.020801411  0.004037867  0.017878113
6 -0.0045285773 -0.0100065588  0.041283771 -0.010697721  0.019126004
            24           25           26            27           28
1  0.005493446 -0.005117578  0.002417232  0.0029094274  0.007428524
2 -0.016486206  0.001868707 -0.018987153  0.0160369058  0.009720300
3  0.003452780  0.004296271  0.002951245  0.0001131737 -0.007050715
4 -0.002556673  0.006071483 -0.015038645 -0.0211500743  0.004213714
5 -0.007911431 -0.005420122  0.001394422  0.0072501776  0.005088708
6  0.018838713 -0.024894516 -0.001149155 -0.0060146780 -0.008371050
              29
1  0.01521460663
2  0.00916700902
3 -0.00434151837
4  0.01636142760
5  0.00008501225
6 -0.02609771673

Clustering vector:
                          Angola                          Armenia 
                               3                                3 
                      Azerbaijan                          Bahrain 
                               1                                3 
                      Bangladesh             Bosnia & Herzegovina 
                               3                                4 
                          Brunei                       Cape Verde 
                               3                                3 
                         Comoros                         Djibouti 
                               3                                3 
                   Guinea-Bissau                          Namibia 
                               3                                3 
                     North Korea                            Qatar 
                               3                                3 
             São Tomé & Príncipe                       Seychelles 
                               3                                1 
            United Arab Emirates                          Vanuatu 
                               3                                5 
                         Vietnam                            Yemen 
                               3                                3 
                         Algeria                Antigua & Barbuda 
                               3                                5 
                           China              Congo - Brazzaville 
                               1                                3 
                        Dominica       German Democratic Republic 
                               1                                2 
                          Guinea                           Jordan 
                               3                                3 
                          Kuwait                            Libya 
                               3                                3 
                        Malaysia                             Mali 
                               3                                3 
                      Mauritania                           Monaco 
                               3                                4 
                        Mongolia                          Morocco 
                               1                                3 
                      Mozambique                             Oman 
                               3                                3 
                         Senegal                          Somalia 
                               3                                3 
               St. Kitts & Nevis                        St. Lucia 
                               5                                5 
        St. Vincent & Grenadines                            Sudan 
                               5                                3 
                        Suriname                       Tajikistan 
                               3                                6 
                        Tanzania                          Tunisia 
                               3                                3 
                          Uganda          Yemen People's Republic 
                               3                                2 
                          Zambia                         Zimbabwe 
                               3                                3 
                        Kiribati                            Nauru 
                               6                                6 
                          Taiwan                      Timor-Leste 
                               2                                6 
                           Tonga                     Turkmenistan 
                               4                                6 
                          Tuvalu      Federal Republic of Germany 
                               6                                5 
                         Andorra                           Belize 
                               4                                5 
                         Croatia                          Czechia 
                               4                                4 
                         Eritrea                          Estonia 
                               6                                4 
                         Georgia                          Germany 
                               4                                4 
                         Grenada                       Kazakhstan 
                               5                                6 
                      Kyrgyzstan                           Latvia 
                               6                                4 
                   Liechtenstein                        Lithuania 
                               4                                4 
                         Moldova                       Montenegro 
                               4                                4 
                 North Macedonia                         Slovakia 
                               4                                4 
                        Slovenia                      South Korea 
                               4                                1 
                     Switzerland                      South Sudan 
                               4                                6 
                           Benin                     Burkina Faso 
                               3                                3 
                          Guyana                          Jamaica 
                               3                                5 
                        Maldives                          Nigeria 
                               3                                3 
                       Singapore                        Sri Lanka 
                               3                                3 
             Yemen Arab Republic                           Bhutan 
                               2                                3 
               Equatorial Guinea                      Afghanistan 
                               5                                3 
                            Cuba                        Indonesia 
                               3                                3 
                            Iran                          Lebanon 
                               3                                3 
                        Pakistan                     Saudi Arabia 
                               3                                3 
                           Syria                           Turkey 
                               3                                5 
                         Lesotho                            Malta 
                               3                                5 
               Trinidad & Tobago                   Czechoslovakia 
                               3                                2 
                      San Marino                       Uzbekistan 
                               4                                6 
                       Mauritius                            Palau 
                               3                                1 
                           India                         Botswana 
                               3                                3 
                      Costa Rica                      El Salvador 
                               3                                5 
                            Peru                      Philippines 
                               3                                3 
                        Thailand                          Burundi 
                               3                                3 
                           Gabon                           Cyprus 
                               3                                5 
                        Ethiopia                            Niger 
                               3                                3 
                            Togo                         Barbados 
                               3                                5 
                         Liberia                     Sierra Leone 
                               5                                3 
                        Cambodia                         Eswatini 
                               3                                5 
                Congo - Kinshasa                           Gambia 
                               5                                3 
                         Bahamas                             Iraq 
                               5                                3 
                      Yugoslavia                 Papua New Guinea 
                               3                                5 
                           Egypt                         Honduras 
                               3                                5 
                           Kenya                         Colombia 
                               3                                3 
                          Mexico                       Madagascar 
                               3                                3 
                            Laos                             Fiji 
                               3                                5 
                           Nepal                         Cameroon 
                               3                                5 
                            Chad         Central African Republic 
                               3                                5 
                         Uruguay                  Solomon Islands 
                               5                                5 
                   Côte d’Ivoire                            Ghana 
                               5                                3 
                           Haiti                            Samoa 
                               5                                5 
                         Albania                          Ecuador 
                               1                                3 
              Dominican Republic                           Rwanda 
                               5                                5 
                 Myanmar (Burma)                        Guatemala 
                               3                                5 
                          Panama                          Bolivia 
                               5                                3 
                    South Africa                            Chile 
                               6                                5 
                       Nicaragua                        Venezuela 
                               3                                3 
                         Belarus                          Finland 
                               1                                5 
                          Brazil                          Ukraine 
                               3                                1 
                       Argentina                         Bulgaria 
                               3                                1 
                         Romania                           Russia 
                               1                                1 
                        Paraguay                           Malawi 
                               5                                5 
                         Hungary                 Marshall Islands 
                               1                                1 
                         Austria                           Poland 
                               5                                1 
                          Sweden                          Ireland 
                               5                                5 
                         Iceland                           Norway 
                               5                                5 
                     New Zealand                           Greece 
                               5                                5 
                         Denmark Micronesia (Federated States of) 
                               5                                1 
                           Spain                        Australia 
                               5                                5 
                           Japan                           Canada 
                               5                                5 
                     Netherlands                         Portugal 
                               5                                5 
                      Luxembourg                          Belgium 
                               5                                5 
                           Italy                   United Kingdom 
                               5                                5 
                          France                           Israel 
                               5                                5 
                   United States                         Zanzibar 
                               5                                3 

Within cluster sum of squares by cluster:
[1] 2.710458 1.795699 4.722650 2.984536 7.515767 3.989531
 (between_SS / total_SS =  15.3 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"      
# km.res_all_6$cluster
table(km.res_all_6$cluster)

 1  2  3  4  5  6 
17  5 89 19 58 12 
aggregate(svd_dimen_all_wide, by = list(cluster = km.res_all_6$cluster), mean)
svd_km_all_6<- cbind(svd_dimen_all_wide, cluster = km.res_all_6$cluster)
svd_km_all_6
fviz_cluster(km.res_all_6, 
             data = svd_dimen_all_wide,
             palette = c("#00AFBB","#E7B800", "#2E9FDF", "#FC4E07", "#ff5733", "#f333ff"),
             main = "cluster plots",
             ggtheme = theme_clean()
             )

fviz_cluster(km.res_all_6, 
             data = svd_dimen_all_wide,
             palette = c("#00AFBB","#E7B800", "#2E9FDF", "#FC4E07", "#ff5733", "#f333ff"),
             main = "6 cluster plots",
             ggtheme = theme_clean(),
             ellipse.type = "euclid",
             repel = TRUE
             )

svd6_final_df <- rownames_to_column(svd_km_all_6, "country") 
svd6_final_df
svd6_final_df <- svd6_final_df %>% 
  select(country, cluster, everything())

svd6_final_df

1.14.2 World Map 6 clusters

world_data %>%
  left_join((svd6_final_df %>% 
               mutate(country_code = countrycode(country, "country.name", "iso2c"))
             ), 
            by = c("country_code")) %>% 
  filter(!is.na(cluster)) %>% 
  ggplot(aes(x = long, y = lat, group = group, 
             fill = as.factor(cluster))) +
  geom_polygon() +
  theme_map() +
  scale_fill_discrete() +
  labs(fill = "cluster",
       title = "World Clusters based on UN voting",
       caption = "created by ViSa") +
  theme(plot.title = element_text(face = "bold", size = 16))

1.14.3 Country Flags

from: https://github.com/vincentarelbundock/countrycode

library(gt)

Add country Flags to the table

Flags are not appearing in the table

1.14.4 Indian cluster

ind_cluster <- svd6_final_df %>% 
  filter(cluster == (svd6_final_df %>% 
                      filter(country == "India") %>% 
                      pull(cluster) )
  )

ind_cluster
ind_cluster <- ind_cluster %>% 
  mutate(continent = countrycode(country, "country.name", "continent")) %>% 
  select(country, continent, cluster, everything())

ind_cluster

1.14.4.1 Plot Indian cluster

ind_cluster %>% 
  filter(country != "Zanzibar") %>% 
  ggplot(aes(x = `1`, y = `2`, col = continent)) +
  geom_point() +
  geom_text(aes(label = country)) +
  labs(title = "India's cluster-3 with Dim1 & 2 on plot")

1.15 yearwise clustering

1.15.1 2000 onwards

by_country_word_yr_2000 <- unvotes %>% 
  inner_join(rc_words, by = "rcid") %>% 
  mutate(year = year(date)) %>% 
  filter(year > 1999) %>% 
  group_by(word, country, year) %>% 
  summarize_votes(min_votes = 0)

by_country_word_yr_2000
cluster_data_2000 <- by_country_word_yr_2000 %>% 
  widely_svd(country, word, pct_yes)

cluster_data_2000
cluster_data_2000_wide <- pivot_wider(data = cluster_data_2000, id_cols = country, 
                                     names_from = dimension, values_from = value)

cluster_data_2000_wide

converting to dataframe / matrix

cluster_data_2000_wide <- as.data.frame(cluster_data_2000_wide) 

rownames(cluster_data_2000_wide) <- cluster_data_2000_wide$country

cluster_data_2000_wide
cluster_data_2000_wide <- cluster_data_2000_wide[, 2:29]
cluster_data_2000_wide
factoextra::fviz_nbclust(scale(cluster_data_2000_wide), kmeans, method = "wss")

factoextra::fviz_nbclust(scale(cluster_data_2000_wide), kmeans, method = "silhouette")

factoextra::fviz_nbclust(scale(cluster_data_2000_wide), kmeans, method = "gap_stat")
Clustering k = 1,2,..., K.max (= 10): .. done
Bootstrapping, b = 1,2,..., B (= 100)  [one "." per sample]:
.................................................. 50 
.................................................. 100 

set.seed(123)

km.res4_2000 <- kmeans(cluster_data_2000_wide, 6, nstart = 25)
table(km.res4_2000$cluster)

  1   2   3   4   5   6 
  8   7  25 125   6  22 
cluster_data_2000_wide_final <- cbind(cluster_data_2000_wide, cluster = km.res4_2000$cluster)
cluster_data_2000_wide_final
fviz_cluster(km.res4_2000,
             data = cluster_data_2000_wide_final,
             palette = c("#00AFBB","#E7B800", "#2E9FDF", "#FC4E07", "#ff5733", "#f333ff"),
             main = "cluster plots",
             ggtheme = theme_clean(),
             ellipse.type = "euclid",
             repel = TRUE
             )

fviz_cluster(km.res4_2000,
             data = cluster_data_2000_wide_final,
             palette = c("#00AFBB","#E7B800", "#2E9FDF", "#FC4E07", "#ff5733", "#f333ff"),
             main = "cluster plots",
             ggtheme = theme_clean()
             )

cluster_data_2000_wide_final <- rownames_to_column(cluster_data_2000_wide_final, "country") %>% 
  select(country, cluster, everything())

cluster_data_2000_wide_final
world_data %>% 
  left_join((cluster_data_2000_wide_final %>% 
              mutate(country_code = countrycode(country, "country.name", "iso2c"))
            ), 
            by = "country_code") %>% 
  filter(!is.na(cluster)) %>% 
  
  ggplot(aes(x = long, y = lat, group = group, fill = as.factor(cluster))) +
  geom_polygon() +
  theme_map() +
  scale_fill_discrete() +
  labs(fill = "cluster",
     title = "World Clusters based on UN voting year 2000 onwards",
     caption = "created by ViSa") +
  theme(plot.title = element_text(face = "bold", size = 16))

1.15.2 Before 2000

by_country_word_yr_19xx <- unvotes %>% 
  inner_join(rc_words, by = "rcid") %>% 
  mutate(year = year(date)) %>% 
  filter(year <= 1999) %>% 
  group_by(word, country, year) %>% 
  summarize_votes(min_votes = 0)

by_country_word_yr_19xx
cluster_data_19xx <- by_country_word_yr_19xx %>% 
  widely_svd(country, word, pct_yes)

cluster_data_19xx
cluster_data_19xx_wide <- pivot_wider(data = cluster_data_19xx, id_cols = country, 
                                     names_from = dimension, values_from = value)

cluster_data_19xx_wide

converting to dataframe / matrix

cluster_data_19xx_wide <- as.data.frame(cluster_data_19xx_wide) 

rownames(cluster_data_19xx_wide) <- cluster_data_19xx_wide$country

cluster_data_19xx_wide
cluster_data_19xx_wide <- cluster_data_19xx_wide[, 2:30]
cluster_data_19xx_wide
set.seed(123)

km.res4_19xx <- kmeans(cluster_data_19xx_wide, 6, nstart = 25)
table(km.res4_19xx$cluster)

 1  2  3  4  5  6 
75 16 17  5 28 51 
cluster_data_19xx_wide_final <- cbind(cluster_data_19xx_wide, cluster = km.res4_19xx$cluster)
cluster_data_19xx_wide_final
fviz_cluster(km.res4_19xx,
             data = cluster_data_19xx_wide_final,
             palette = c("#00AFBB","#E7B800", "#2E9FDF", "#FC4E07", "#ff5733", "#f333ff"),
             main = "cluster plots",
             ggtheme = theme_clean(),
             ellipse.type = "euclid",
             repel = TRUE
             )

fviz_cluster(km.res4_19xx,
             data = cluster_data_19xx_wide_final,
             palette = c("#00AFBB","#E7B800", "#2E9FDF", "#FC4E07", "#ff5733", "#f333ff"),
             main = "cluster plots",
             ggtheme = theme_clean()
             )

cluster_data_19xx_wide_final <- rownames_to_column(cluster_data_19xx_wide_final, "country") %>% 
  select(country, cluster, everything())

cluster_data_19xx_wide_final
world_data %>% 
  left_join((cluster_data_19xx_wide_final %>% 
              mutate(country_code = countrycode(country, "country.name", "iso2c"))
            ), 
            by = "country_code") %>% 
  filter(!is.na(cluster)) %>% 
  
  ggplot(aes(x = long, y = lat, group = group, fill = as.factor(cluster))) +
  geom_polygon() +
  theme_map() +
  scale_fill_discrete() +
  labs(fill = "cluster",
     title = "World 6 Clusters based on UN voting  in 1900's",
     caption = "created by ViSa") +
  theme(plot.title = element_text(face = "bold", size = 16))

1.16 (attempts)df for all clusters

final_clusters_df <-  svd_dimen_all_wide %>% 
                        rownames_to_column(var = "country")
Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
  cannot coerce class ‘"kmeans"’ to a data.frame
Error in as.data.frame(cluster_res_list) : 
  object 'cluster_res_list' not found
iris
iris_df <- iris %>% 
  as.data.frame() 

rownames(iris_df) <- 1: nrow(iris_df)
iris_df
lapply(1:3,
function(cluster_num){
  cluster_res_list <- as.list(kmeans(iris %>% select(-Species), cluster_num, nstart = 25)) 
 names(cluster_res_list) <- paste("iris_clus", 1:length(cluster_res_list), sep="_")
 list2env(cluster_res_list, envir = .GlobalEnv)
 
 # print(head(cluster_res_list))
 iris_df <- cbind(iris, paste0("iris_clus_", cluster_num))
} )
[[1]]

[[2]]

[[3]]
NA
iris_df
for(cluster_num in 1:3){
  km_cluster_res <- kmeans(iris %>% select(-Species), cluster_num, nstart = 25)
  
  print(assign(paste("iris_clus", cluster_num,sep = "_"),km_cluster_res$cluster))
  
  # iris_df <- cbind(iris, 
  #                   assign(paste("iris_clus", cluster_num,sep = "_"),
  #                          km_cluster_res$cluster)
  # )
  
}
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [39] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [77] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[115] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [39] 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [77] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[115] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [39] 2 2 2 2 2 2 2 2 2 2 2 2 3 3 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 [77] 3 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 3 1 1 1 1 3 1 1 1 1 1 1 3
[115] 3 1 1 1 1 3 1 3 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 3 1 1 1 3 1 1 1 3 1 1 3
# iris_df %>% head()
Error: unexpected '=' in:
"        # tibble(iris_clus = .) %>%
        tibble(paste0("iris_clus_", cluster_num) ="
Error: unexpected '=' in:
"  cbind(iris) %>% 
  rename(paste0("iris_clus_", cluster_num) ="

cbind() doesn’t combine dataframe of 0 rows with df of non 0 rows, so use below way of doing it.

# final_df <- data.frame()
final_df <- list()

for(cluster_num in 1:3){
  km_cluster_res <- kmeans(iris %>% select(-Species), cluster_num, nstart = 25)
  
  iris_results <- as.data.frame(km_cluster_res$cluster)
  names(iris_results) <- paste("iris_clus_", cluster_num, sep="")
  
  final_df <- as.data.frame(cbind(final_df, as.matrix(iris_results)) ) 

}

final_df %>% head()

In below code combining non 0 rows df with same rows df.

final_df <- iris

for(cluster_num in 1:3){
  km_cluster_res <- kmeans(iris %>% select(-Species), cluster_num, nstart = 25)
  
  iris_results <- as.data.frame(km_cluster_res$cluster)
  names(iris_results) <- paste("iris_clus_", cluster_num, sep="")
  
  final_df <- as.data.frame(cbind(final_df, iris_results) ) 
  # print(names(final_df))

}

final_df %>% head()

from: https://stackoverflow.com/questions/66870535/how-to-dynamically-create-variables-and-combine-it-to-the-dataframe-in-r/66871085?noredirect=1#comment118207648_66871085

clusters <- Reduce(cbind, lapply(1:3, function(cluster_num) {

   result <- iris %>% 
        select(-Species) %>% 
        kmeans(centers = cluster_num, nstart = 25) %>% 
        fitted() %>% 
        row.names() %>% 
        tibble(iris_clus = .)

   names(result) <- paste("iris_clus", cluster_num, sep = "_")
   return(result)

}))

cbind(iris, clusters)

1.17 (final)df for all clusters


final_clusters_df <- svd_dimen_all_wide

for(cluster_num in 1:15){
  km_cluster_res <- kmeans(final_clusters_df, cluster_num, nstart = 25)
  
  results <- as.data.frame(km_cluster_res$cluster)
  names(results) <- paste("cluster", cluster_num, sep="_")
  
  final_clusters_df <- as.data.frame(cbind(final_clusters_df, results) ) 

}

final_clusters_df %>% head()

1.18 ggstream

unvotes %>% 
  # mutate_all(as.factor) %>% 
  group_by(years = year(date) , vote) %>% 
  summarise(count = n(), .groups = "drop_last") %>%
  # mutate(pct = count/sum(count)) %>% 
 
  
  ggplot(aes(x = years, y = count, fill = vote)) +
  ggstream::geom_stream(show.legend = FALSE) +
  geom_stream_label(aes(label = vote)) +
  scale_y_continuous(labels = comma) +
  scale_fill_manual(values = wes_palette("Darjeeling2")) +
  theme(panel.grid.major = element_blank()) +
  
  labs(title = "World UN Voting trend over the years",
       y = "", x = "",
       caption = "created by ViSa")

unvotes_plus_continents <-  unvotes %>% 
  mutate(continent = countrycode(country_code, "iso2c", "continent"))

unvotes_plus_continents %>% 
  group_by(continent, year = year(date) , vote) %>% 
  summarise(count = n(), .groups = "drop_last") %>%
  na.omit() %>% 
  # mutate(pct = count/sum(count)) %>% 
 
  
  ggplot(aes(x = year, y = count, fill = vote)) +
  ggstream::geom_stream(show.legend = FALSE) +
  geom_stream_label(aes(label = vote)) +
  scale_y_continuous(labels = comma
                     #, breaks = seq(-2000,2000, 500)
                     ) +
  scale_fill_manual(values = wes_palette("Darjeeling2")) +
  theme(panel.grid.major = element_blank()) +
  facet_wrap(~continent) +
  
  labs(title = "World UN Voting trend over the years by continent",
       y = "", x = "",
       caption = "created by ViSa")

1.19 End of Notebook

LS0tDQp0aXRsZTogIlVOIFZvdGVzIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogeWVzDQogICAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19kZXB0aDogNg0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAnNicNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KDQojIFVOIFZvdGVzIEFuYWx5c2lzDQoNCiMjIG9wdGlvbnMgJiBzZXR0aW5ncw0KDQpjaHVuayBvcHRpb25zDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgZHBpID0gMzAwLCBvdXQud2lkdGggPSAiMTAwJSIsYXR0ci5vdXRwdXQ9J3N0eWxlPSJtYXgtaGVpZ2h0OiAzMDBweDsiJykNCmBgYA0KDQpDU1MgZm9yIHNjcm9sbGFibGUgb3V0cHV0ICYgSGVhZGVyIGNvbG9ycw0KDQpgYGB7Y3NzLCBlY2hvPUZBTFNFLCBpbmNsdWRlID0gRkFMU0V9DQouc2Nyb2xsLTEwMCB7DQogIG1heC1oZWlnaHQ6IDEwMHB4Ow0KICBvdmVyZmxvdy15OiBhdXRvOw0KICBiYWNrZ3JvdW5kLWNvbG9yOiBpbmhlcml0Ow0KfQ0KDQp0Ym9keSB0cjpob3ZlciB7DQogIGJhY2tncm91bmQ6ICNkZGRkZGQ7DQp9DQoNCg0KaDEsICNUT0M+dWw+bGkgew0KICBjb2xvcjogI0I2NEQzQTsNCn0NCg0KaDIsICNUT0M+dWw+dWw+bGkgew0KICBjb2xvcjogIzAwMDAwMDsNCn0NCg0KaDMsICNUT0M+dWw+dWw+dWw+bGkgew0KICBjb2xvcjogIzY0M2NiMjsNCn0NCg0KaDQsICNUT0M+dWw+dWw+dWw+dWw+bGkgew0KICBjb2xvcjogI2FlMDA1ODsNCn0NCg0KaDUsICNUT0M+dWw+dWw+dWw+dWw+dWw+bGkgew0KICBjb2xvcjogI2ZmYTQ0NzsNCn0NCg0KaDYsICNUT0M+dWw+dWw+dWw+dWw+dWw+dWw+bGkgew0KICBjb2xvcjogI0RBRTNEOTsNCn0NCg0KDQpgYGANCg0KVHVybmluZyBzY2llbnRpZmljIC8gRXhwb25lbnRpYWwgbnVtYmVycyBvZmYNCg0KYGBge3J9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0Kb3B0aW9ucyhyZWFkci5zaG93X3Byb2dyZXNzID0gRkFMU0UpDQpgYGANCg0KIyMgU291cmNlDQoNCkRhdmlkIFJvYmluc29uIHRpZHl0dWVzZGF5OiA8aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj0yUmFkWnJwelRhQT4NCg0KIyMgTG9hZGluZyBsaWJzDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeSh0aWR5dHVlc2RheVIpDQpsaWJyYXJ5KHRpZHl0ZXh0KQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZ2x1ZSkNCmxpYnJhcnkoZ2d0ZXh0KQ0KbGlicmFyeSh3aWR5cikNCmxpYnJhcnkoY291bnRyeWNvZGUpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KGdnc3RyZWFtKQ0KbGlicmFyeSh3ZXNhbmRlcnNvbikgICMgY29sb3IgcGFsbGV0ZQ0KYGBgDQoNCiMjIENyZWF0aW5nICYgc2V0dGluZyBjdXN0b20gdGhlbWUNCg0KYGBge3J9DQoNCnRoZW1lX3ZpbnlfYnJpZ2h0IDwtIGZ1bmN0aW9uKCl7DQogIA0KICBsaWJyYXJ5KGdndGhlbWVzKQ0KICANCiAgZ2d0aGVtZXM6OnRoZW1lX2ZpdmV0aGlydHllaWdodCgpICUrcmVwbGFjZSUNCiAgDQogIHRoZW1lKA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSwNCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSwNCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpLA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSwNCiAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSAic2VyaWYiLCBtYXJnaW49bWFyZ2luKDAsMCwxNSwwKSksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSxmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gInNlcmlmIiwgc2l6ZSA9IDkpLA0KICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEsICBzaXplID0gOCkNCiAgICAgICkNCiAgfQ0KDQp0aGVtZV9zZXQodGhlbWVfdmlueV9icmlnaHQoKSkNCmBgYA0KDQojIyBMb2FkIERhdGENCg0KYGBge3J9DQp0dCA8LSB0dF9sb2FkKCIyMDIxLTAzLTIzIikNCg0KdHQNCmBgYA0KDQpgYGB7cn0NCnVudm90ZXMgPC0gdHQkdW52b3Rlcw0KDQpoZWFkKHVudm90ZXMpDQpgYGANCg0KYGBge3J9DQp1bnZvdGVzICU+JSANCiAgbXV0YXRlX2FsbChhcy5mYWN0b3IpICU+JSANCiAgc3VtbWFyeSgpDQpgYGANCg0KYGBge3J9DQp1bnZvdGVzICU+JSANCiAgbXV0YXRlX2FsbChhcy5mYWN0b3IpICU+JSANCiAgZ3JvdXBfYnkoY291bnRyeSwgdm90ZSkgJT4lIA0KICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQ0KICBtdXRhdGUocGN0ID0gY291bnQvc3VtKGNvdW50KSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lDQogIGZpbHRlcihjb3VudHJ5ID09ICJJbmRpYSIpDQpgYGANCg0KIyMjIHRvcCBib3R0b20gY291bnRyaWVzIGJ5IHZvdGUgdHlwZQ0KDQpgYGB7cn0NCnVudm90ZXMgJT4lIA0KICBtdXRhdGVfYWxsKGFzLmZhY3RvcikgJT4lIA0KICBncm91cF9ieShjb3VudHJ5LCB2b3RlKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wX2xhc3QiKSAlPiUNCiAgbXV0YXRlKHBjdCA9IGNvdW50L3N1bShjb3VudCkpICU+JSANCiAgDQogIGdyb3VwX2J5KHZvdGUpICU+JQ0KICBzbGljZV9tYXgocGN0LCBuID0gMTApICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBzdHJfd3JhcChjb3VudHJ5LCB3aWR0aCA9IDIwKSkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gcGN0LCB5ID0gdGlkeXRleHQ6OnJlb3JkZXJfd2l0aGluKGNvdW50cnksIGJ5ID0gcGN0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aGluID0gdm90ZSkpKSArDQogIGdlb21fY29sKCkgKw0KICBmYWNldF93cmFwKH52b3RlLCBzY2FsZXMgPSAiZnJlZV95IikgKw0KICBzY2FsZV95X3Jlb3JkZXJlZCgpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJ0b3AgMTAgY291bnRyaWVzIGJ5IHZvdGUgdHlwZSIsDQogICAgICAgeSA9ICIiLCB4ID0gInBlcmNlbnRhZ2Ugb2Ygdm90ZSB0eXBlIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCnVudm90ZXMgJT4lIA0KICBtdXRhdGVfYWxsKGFzLmZhY3RvcikgJT4lIA0KICBncm91cF9ieShjb3VudHJ5LCB2b3RlKSAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wX2xhc3QiKSAlPiUNCiAgbXV0YXRlKHBjdCA9IGNvdW50L3N1bShjb3VudCkpICU+JSANCiAgDQogIGdyb3VwX2J5KHZvdGUpICU+JQ0KICBhcnJhbmdlKGRlc2MocGN0KSkgJT4lIA0KICBzbGljZShjKDE6MTAsIChuKCkgLSAxMCk6bigpICkpICU+JSAgIyB0aGlzIHNlbGVjdHMgYm90aCB0b3AgJiBib3R0b20gMTANCiAgbXV0YXRlKGNvdW50cnkgPSBzdHJfd3JhcChjb3VudHJ5LCB3aWR0aCA9IDIwKSkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gcGN0LCB5ID0gdGlkeXRleHQ6OnJlb3JkZXJfd2l0aGluKGNvdW50cnksIGJ5ID0gcGN0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aGluID0gdm90ZSkpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGZhY2V0X3dyYXAofnZvdGUsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIHNjYWxlX3lfcmVvcmRlcmVkKCkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gInRvcCAxMCAmIGJvdHRvbSAxMCBjb3VudHJpZXMgYnkgZWFjaCB2b3RlIHR5cGUiLA0KICAgICAgIHkgPSAiIiwgeCA9ICJwZXJjZW50YWdlIG9mIHZvdGUgdHlwZSIsDQogICAgICAgY2FwdGlvbiA9ICJjcmVhdGVkIGJ5IFZpU2EiKQ0KYGBgDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQp1bnZvdGVzICU+JSANCiAgbXV0YXRlX2FsbChhcy5mYWN0b3IpICU+JSANCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIA0KICBtdXRhdGUodG90YWxfdm90ZXMgID0gbigpKSAlPiUNCiAgDQogIGdyb3VwX2J5KGNvdW50cnksIHZvdGUpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gImRyb3BfbGFzdCIsDQogICAgICAgICAgICB0b3RhbF92b3RlcyA9IGZpcnN0KHRvdGFsX3ZvdGVzKSkgJT4lDQogIG11dGF0ZShwY3QgPSBjb3VudC9zdW0oY291bnQpKSAlPiUgDQogIA0KICBncm91cF9ieSh2b3RlKSAlPiUNCiAgYXJyYW5nZShkZXNjKHBjdCkpICU+JSANCiAgc2xpY2UoYygxOjEwLCAobigpIC0gMTApOm4oKSApKSAlPiUgICMgdGhpcyBzZWxlY3RzIGJvdGggdG9wICYgYm90dG9tIDEwDQogIG11dGF0ZShjb3VudHJ5ID0gc3RyX3dyYXAoY291bnRyeSwgd2lkdGggPSAyMCkpICU+JSANCiAgDQogIGdncGxvdChhZXMoeCA9IHBjdCwgDQogICAgICAgICAgICAgeSA9IHRpZHl0ZXh0OjpyZW9yZGVyX3dpdGhpbihjb3VudHJ5LCBieSA9IHBjdCwgd2l0aGluID0gdm90ZSkpKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemUgPSB0b3RhbF92b3RlcykpICsNCiAgZmFjZXRfd3JhcCh+dm90ZSwgc2NhbGVzID0gImZyZWVfeSIpICsNCiAgc2NhbGVfeV9yZW9yZGVyZWQoKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgbGFicyh0aXRsZSA9ICJ0b3AgMTAgJiBib3R0b20gMTAgY291bnRyaWVzIGJ5IGVhY2ggdm90ZSB0eXBlIiwNCiAgICAgICB5ID0gIiIsIHggPSAicGVyY2VudGFnZSBvZiB2b3RlIHR5cGUiLA0KICAgICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikNCmBgYA0KDQpgYGB7cn0NCnVudm90ZXMgPC0gdW52b3RlcyAlPiUgDQogIG11dGF0ZSh2b3RlX251bWJlciA9IG1hdGNoKHZvdGUsIGMoIm5vIiwiYWJzdGFpbiIsInllcyIpKSAtMikNCg0KdW52b3Rlcw0KYGBgDQoNCnNhdmluZyBvYmplY3QgZm9yIGZsZXhkYXNiaG9hcmQNCg0KYGBge3J9DQpmbGV4X3RvcGJvdHRvbSA8LSB1bnZvdGVzICU+JSANCiAgbXV0YXRlX2FsbChhcy5mYWN0b3IpICU+JSANCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIA0KICBtdXRhdGUodG90YWxfdm90ZXMgID0gbigpKSAlPiUNCiAgDQogIGdyb3VwX2J5KGNvdW50cnksIHZvdGUpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gImRyb3BfbGFzdCIsDQogICAgICAgICAgICB0b3RhbF92b3RlcyA9IGZpcnN0KHRvdGFsX3ZvdGVzKSkgJT4lDQogIG11dGF0ZShwY3QgPSBjb3VudC9zdW0oY291bnQpLA0KICAgICAgICAgY291bnRyeSA9IHN0cl93cmFwKGNvdW50cnksIHdpZHRoID0gMjApKSAlPiUgDQogIA0KICBncm91cF9ieSh2b3RlKSAlPiUNCiAgYXJyYW5nZShkZXNjKHBjdCkpIA0KICANCmZsZXhfdG9wYm90dG9tICU+JSAgIA0KICBzbGljZShjKDE6MTAsIChuKCkgLSAxMCk6bigpICkpICU+JSAgIyB0aGlzIHNlbGVjdHMgYm90aCB0b3AgJiBib3R0b20gMTANCiAgDQogIGdncGxvdChhZXMoeCA9IHBjdCwgDQogICAgICAgICAgICAgeSA9IHRpZHl0ZXh0OjpyZW9yZGVyX3dpdGhpbihjb3VudHJ5LCBieSA9IHBjdCwgd2l0aGluID0gdm90ZSkpKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemUgPSB0b3RhbF92b3RlcykpICsNCiAgZmFjZXRfd3JhcCh+dm90ZSwgc2NhbGVzID0gImZyZWVfeSIpICsNCiAgc2NhbGVfeV9yZW9yZGVyZWQoKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgbGFicyh0aXRsZSA9ICJ0b3AgMTAgJiBib3R0b20gMTAgY291bnRyaWVzIGJ5IGVhY2ggdm90ZSB0eXBlIiwNCiAgICAgICB5ID0gIiIsIHggPSAicGVyY2VudGFnZSBvZiB2b3RlIHR5cGUiLA0KICAgICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikNCmBgYA0KDQpgYGB7cn0NCnVudm90ZXMgJT4lIA0KICBjb3VudCh2b3RlLCB2b3RlX251bWJlcikNCmBgYA0KDQpgYGB7cn0NCmJ5X2NvdW50cnkgPC0gdW52b3RlcyAlPiUgDQogIGdyb3VwX2J5KGNvdW50cnkpICU+JSANCiAgc3VtbWFyaXNlKG5fdm90ZXMgPSBuKCksDQogICAgICAgICAgICBuX3llcyA9IHN1bSh2b3RlID09ICJ5ZXMiKSwNCiAgICAgICAgICAgIHBjdF95ZXMgPSBuX3llcyAvIG5fdm90ZXMpICU+JSANCiAgYXJyYW5nZShkZXNjKHBjdF95ZXMpKSAlPiUgDQogIGZpbHRlcihuX3ZvdGVzID49IDEwMCkNCg0KYnlfY291bnRyeQ0KYGBgDQoNCiMjIyBmbiBzdW1tYXJpemVfdm90ZXMoKQ0KDQpgYGB7cn0NCnN1bW1hcml6ZV92b3RlcyA8LSBmdW5jdGlvbihkZiwgbWluX3ZvdGVzID0gMTApew0KICBkZiAlPiUgIA0KICBzdW1tYXJpc2Uobl92b3RlcyA9IG4oKSwNCiAgICAgICAgICAgIG5feWVzID0gc3VtKHZvdGUgPT0gInllcyIpLA0KICAgICAgICAgICAgcGN0X3llcyA9IG5feWVzIC8gbl92b3RlcykgJT4lIA0KICBhcnJhbmdlKGRlc2MocGN0X3llcykpICU+JSANCiAgZmlsdGVyKG5fdm90ZXMgPj0gbWluX3ZvdGVzKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KYnlfY291bnRyeSA8LSB1bnZvdGVzICU+JSANCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIA0KICBzdW1tYXJpemVfdm90ZXMoKQ0KDQpieV9jb3VudHJ5DQpgYGANCg0KIyMjIHRvcCBib3R0b20gZm9yIHllcyB2b3Rlcw0KDQpgYGB7cn0NCmJ5X2NvdW50cnkgJT4lDQogIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY291bnRyeSwgcGN0X3llcykpICU+JSANCiAgc2xpY2UoYygxOjEwLCAobigpIC0gMTApOm4oKSApKSAlPiUgDQogIA0KICBnZ3Bsb3QoYWVzKHggPSBwY3RfeWVzLCB5ID0gY291bnRyeSkpICsNCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IG5fdm90ZXMpKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArDQogIGxhYnModGl0bGUgPSAiVG9wICYgYm90dG9tIGNvdW50cmllcyB3aXRoICUgb2YgeWVzIHZvdGVzIGluIFVOIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpDQpgYGANCg0KIyMjIExlYXN0IHllcyB2b3Rlcw0KDQpgYGB7cn0NCmJ5X2NvdW50cnkgJT4lDQogIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY291bnRyeSwgcGN0X3llcykpICU+JSANCiAgc2xpY2VfbWluKHBjdF95ZXMsIG4gPSAyMCkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gcGN0X3llcywgeSA9IGNvdW50cnkpKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkgKw0KICBsYWJzKHRpdGxlID0gIkNvdW50cmllcyB3aXRoIGxlYXN0ICUgb2YgeWVzIHZvdGVzIGluIFVOIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgY2FwdGlvbiA9ICJjcmVhdGVkIGJ5IFZpU2EiKQ0KYGBgDQoNCiMjIyByb2xsX2NhbGxzIGRmDQoNCmBgYHtyfQ0KdHQkcm9sbF9jYWxscw0KYGBgDQoNCmBgYHtyfQ0KdW52b3RlcyA8LSB1bnZvdGVzICU+JSANCiAgbGVmdF9qb2luKHR0JHJvbGxfY2FsbHMgJT4lIA0KICAgICAgICAgICAgICBzZWxlY3QocmNpZCwgZGF0ZSwgYW1lbmQpLCBieSA9ICJyY2lkIikgDQoNCnVudm90ZXMNCmBgYA0KDQpgYGB7cn0NCmJ5X3llYXIgPC0gdW52b3RlcyAlPiUgDQogIGdyb3VwX2J5KHllYXIgPSB5ZWFyKGRhdGUpKSAlPiUgDQogIHN1bW1hcml6ZV92b3RlcygpDQoNCmJ5X3llYXINCmBgYA0KDQpgYGB7cn0NCmJ5X3llYXIgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcGN0X3llcykpICsNCiAgZ2VvbV9saW5lKCBzaXplID0gLjkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICsNCiAgZXhwYW5kX2xpbWl0cyh5ID0gMCkNCmBgYA0KDQpgYGB7cn0NCmJ5X2NvdW50cnlfeWVhciA8LSB1bnZvdGVzICU+JSANCiAgZ3JvdXBfYnkoeWVhciA9IHllYXIoZGF0ZSksIA0KICAgICAgICAgICBjb3VudHJ5KSAlPiUgDQogIHN1bW1hcml6ZV92b3RlcygpDQoNCmJ5X2NvdW50cnlfeWVhcg0KYGBgDQoNCmBgYHtyfQ0KYnlfY291bnRyeV95ZWFyICU+JSANCiAgZmlsdGVyKGNvdW50cnkgJWluJSBjKCJVbml0ZWQgU3RhdGVzIiwgIkNhbmFkYSIsICJNYWxpIikpICU+JSANCiAgbXV0YXRlKGNvdW50cnkgPSBmY3RfcmVvcmRlcihjb3VudHJ5LCBwY3RfeWVzKSkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHBjdF95ZXMsIGNvbCA9IGNvdW50cnkpKSArDQogIGdlb21fbGluZShzaXplID0gMC45KSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArDQogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICBleHBhbmRfbGltaXRzKHkgPSAwKSArDQogIGxhYnModGl0bGUgPSAiJSB5ZXMgYnkgY291bnRyaWVzIG92ZXIgdGhlIHllYXJzIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpDQpgYGANCg0KYGBge3J9DQpjb3VudHJ5X3llc19saW5lIDwtIGZ1bmN0aW9uKGZpbHRlcl9saXN0ID0gYygiSW5kaWEiKSl7DQogICAgYnlfY291bnRyeV95ZWFyICU+JSANCiAgICBmaWx0ZXIoY291bnRyeSAlaW4lIGZpbHRlcl9saXN0KSAlPiUgDQogICAgbXV0YXRlKGNvdW50cnkgPSBmY3RfcmVvcmRlcihjb3VudHJ5LCBwY3RfeWVzKSkgJT4lIA0KICAgIA0KICAgIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBwY3RfeWVzLCBjb2wgPSBjb3VudHJ5KSkgKw0KICAgIGdlb21fbGluZShzaXplID0gMC45KSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICsNCiAgICAjIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICAgIGV4cGFuZF9saW1pdHMoeSA9IDApKw0KICAgIGxhYnModGl0bGUgPSAiJSB5ZXMgdm90ZXMgYnkgY291bnRyaWVzIG92ZXIgdGhlIHllYXJzIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpDQp9DQpgYGANCg0KYGBge3J9DQpjb3VudHJ5X3llc19saW5lKGZpbHRlcl9saXN0ID0gYygiSW5kaWEiLCAiUnVzc2lhIiwgIlVuaXRlZCBTdGF0ZXMiLCAiQ2hpbmEiKSkNCmBgYA0KDQpgYGB7cn0NCmNvdW50cnlfeWVzX2xpbmVfZmFjZXQgPC0gZnVuY3Rpb24oZmlsdGVyX2xpc3QgPSBjKCJJbmRpYSIpKXsNCiAgICBieV9jb3VudHJ5X3llYXIgJT4lIA0KICAgIGZpbHRlcihjb3VudHJ5ICVpbiUgZmlsdGVyX2xpc3QpICU+JSANCiAgICBtdXRhdGUoY291bnRyeSA9IGZjdF9yZW9yZGVyKGNvdW50cnksIHBjdF95ZXMpKSAlPiUgDQogICAgDQogICAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHBjdF95ZXMsIGNvbCA9IGNvdW50cnkpKSArDQogICAgZ2VvbV9saW5lKHNpemUgPSAwLjksIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkgKw0KICAgICMgc2NhbGVfY29sb3JfZGlzY3JldGUoZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKSArDQogICAgZXhwYW5kX2xpbWl0cyh5ID0gMCkrDQogICAgZmFjZXRfd3JhcCh+Y291bnRyeSkgKw0KICAgIGxhYnModGl0bGUgPSAiJSB5ZXMgYnkgY291bnRyaWVzIG92ZXIgdGhlIHllYXJzIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpDQp9DQpgYGANCg0KYGBge3J9DQpjb3VudHJ5X3llc19saW5lX2ZhY2V0KGMoIkluZGlhIiwiUnVzc2lhIiwiQ2hpbmEiLCJGcmFuY2UiLCJQYWtpc3RhbiIsIlN3ZWRlbiIpKQ0KYGBgDQoNCmBgYHtyfQ0KY291bnRyeV95ZXNfbGluZV9mYWNldChjKCJJbmRpYSIsIlJ1c3NpYSIsIkZyYW5jZSIsIkdlcm1hbnkiLCJVbml0ZWQgS2luZ2RvbSIsIlR1cmtleSIpKQ0KYGBgDQoNCkZyb20gYWJvdmUgY2hhcnRzIGxvdCBvZiBjb3VudHJpZXMgaXMgY2xvc2UgdG8gNzUlIHllc192b3RlIG5vdyBhbmQgdGhpcyBoYXBwZW5lZCBmcm9tIDE5OTAncy4gU29tZSBFdXJvcGVhbiAmIFdlc3Rlcm4gY291bnRyaWVzIGdvZXMgbG93ZXIgdGhhbiA3NSUgd2hpY2ggYXJlIG1vc3RseSBOQVRPIGFsbGllcy4NCg0KIyMjIE92ZXJhbGwgQ291bnRyaWVzIGF2Zw0KDQpgYGB7cn0NCmJ5X2NvdW50cnlfeWVhciA8LSB1bnZvdGVzICU+JSANCiAgYmluZF9yb3dzKHVudm90ZXMgJT4lIG11dGF0ZShjb3VudHJ5ID0gIk92ZXJhbGwiKSkgJT4lIA0KICANCiAgZ3JvdXBfYnkoeWVhciA9IHllYXIoZGF0ZSksDQogICAgICAgICAgIGNvdW50cnkpICU+JSANCiAgc3VtbWFyaXplX3ZvdGVzKCkNCiAgDQpieV9jb3VudHJ5X3llYXIgJT4lICANCiAgZmlsdGVyKGNvdW50cnkgPT0gIk92ZXJhbGwiKQ0KYGBgDQoNCmBgYHtyfQ0KY291bnRyeV95ZXNfbGluZSA8LSBmdW5jdGlvbihmaWx0ZXJfbGlzdCA9IGMoIkluZGlhIikpew0KICAgIGJ5X2NvdW50cnlfeWVhciAlPiUgDQogICAgZmlsdGVyKGNvdW50cnkgJWluJSBmaWx0ZXJfbGlzdCkgJT4lIA0KICAgIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY291bnRyeSwgcGN0X3llcykpICU+JSANCiAgICANCiAgICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcGN0X3llcykpICsNCiAgICBnZW9tX2xpbmUoZGF0YSA9IGJ5X3llYXIsIGx0eSA9IDEsIHNpemUgPSAxLjgsIGFscGhhID0gMC4zKSArDQogICAgZ2VvbV9saW5lKGFlcyhjb2wgPSBjb3VudHJ5KSwgc2l6ZSA9IDAuOSkgKw0KICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArDQogICMgc2NhbGVfY29sb3JfZGlzY3JldGUoZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKSArDQogICAgZXhwYW5kX2xpbWl0cyh5ID0gMCkrDQogICAgbGFicyh0aXRsZSA9ICIlIHllcyBieSBjb3VudHJpZXMgb3ZlciB0aGUgeWVhcnMgd2l0aCB3b3JsZCBhdmVyYWdlIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpICsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwNCiAgICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KY291bnRyeV95ZXNfbGluZShmaWx0ZXJfbGlzdCA9IGMoIkluZGlhIiwgIlJ1c3NpYSIsICJVbml0ZWQgU3RhdGVzIiwgIkNoaW5hIikpDQpgYGANCg0KYGBge3J9DQpjb3VudHJ5X2xpc3QgPC0gdW52b3RlcyAlPiUgDQogIGRpc3RpbmN0KGNvdW50cnkpICU+JSANCiAgcHVsbCgpDQoNCmNvdW50cnlfbGlzdA0KYGBgDQoNCiMjIFdvcmxkIE1hcA0KDQpgYGB7cn0NCm1hcF9kYXRhKCJ3b3JsZCIpICU+JQ0KICBmaWx0ZXIocmVnaW9uICE9ICJBbnRhcmN0aWNhIikgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCkpICsNCiAgZ2VvbV9wb2x5Z29uKCkgKw0KICB0aGVtZV9tYXAoKQ0KYGBgDQoNCiMjIyBmbiBzdW1tYXJpemVfdm90ZXMoKQ0KDQpgYGB7cn0NCnN1bW1hcml6ZV92b3RlcyA8LSBmdW5jdGlvbihkZiwgbWluX3ZvdGVzID0gMTApew0KICBkZiAlPiUgIA0KICBzdW1tYXJpc2Uobl92b3RlcyA9IG4oKSwNCiAgICAgICAgICAgIG5feWVzID0gc3VtKHZvdGUgPT0gInllcyIpLA0KICAgICAgICAgICAgcGN0X3llcyA9IG5feWVzIC8gbl92b3RlcywNCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSANCiAgYXJyYW5nZShkZXNjKHBjdF95ZXMpKSAlPiUgDQogIGZpbHRlcihuX3ZvdGVzID49IG1pbl92b3RlcykNCn0NCmBgYA0KDQpgYGB7cn0NCmJ5X2NvdW50cnkgPC0gdW52b3RlcyAlPiUgDQogIGdyb3VwX2J5KGNvdW50cnksIGNvdW50cnlfY29kZSkgJT4lIA0KICBzdW1tYXJpemVfdm90ZXMoKQ0KDQpieV9jb3VudHJ5DQpgYGANCg0KYGBge3J9DQpieV9jb3VudHJ5X3llYXIgPC0gdW52b3RlcyAlPiUgDQogIGdyb3VwX2J5KHllYXIgPSB5ZWFyKGRhdGUpLCANCiAgICAgICAgICAgY291bnRyeSwNCiAgICAgICAgICAgY291bnRyeV9jb2RlKSAlPiUgDQogIHN1bW1hcml6ZV92b3RlcygpDQoNCmJ5X2NvdW50cnlfeWVhcg0KYGBgDQoNCiMjIyB3b3JsZCBtYXANCg0KYGBge3J9DQpsaWJyYXJ5KGZ1enp5am9pbikNCmBgYA0KDQpgYGB7cn0NCndvcmxkX2RhdGEgPC0gbWFwX2RhdGEoIndvcmxkIikgJT4lIA0KICBmaWx0ZXIocmVnaW9uICE9ICJBbnRhcmN0aWNhIikgJT4lDQogIGFzX3RpYmJsZSgpICU+JSANCiAgZnV6enlqb2luOjpyZWdleF9sZWZ0X2pvaW4obWFwczo6aXNvMzE2NiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KG1hcG5hbWUsIGNvdW50cnlfY29kZSA9IGEyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhyZWdpb24gPSAibWFwbmFtZSIpKQ0KDQp3b3JsZF9kYXRhDQpgYGANCg0KYGBge3J9DQp3b3JsZF9kYXRhICU+JQ0KICBsZWZ0X2pvaW4oYnlfY291bnRyeSwgYnkgPSAiY291bnRyeV9jb2RlIikgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IHBjdF95ZXMpKSArDQogIGdlb21fcG9seWdvbigpICsNCiAgdGhlbWVfbWFwKCkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAicmVkIiwgaGlnaCA9ICJibHVlIiwgDQogICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gLjYsIGxhYmVscyA9IHBlcmNlbnQpICsNCiAgbGFicyhmaWxsID0gIiUgeWVzIHZvdGUiLA0KICAgICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikNCmBgYA0KDQojIyBieSBjb250aW5ldA0KDQpgYGB7cn0NCmxpYnJhcnkoY291bnRyeWNvZGUpDQpgYGANCg0KYGBge3J9DQp1bnZvdGVzICU+JSANCiAgbXV0YXRlKGNvbnRpbmVudCA9IGNvdW50cnljb2RlKGNvdW50cnlfY29kZSwgImlzbzJjIiwgImNvbnRpbmVudCIpKSAlPiUgDQogIGdyb3VwX2J5KGNvbnRpbmVudCwgeWVhciA9IHllYXIoZGF0ZSkpICU+JSANCiAgc3VtbWFyaXplX3ZvdGVzKCkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKGNvbnRpbmVudCkpICU+JSANCiAgDQogIG11dGF0ZShjb3VudHJ5ID0gZmN0X3Jlb3JkZXIoY29udGluZW50LCBwY3RfeWVzKSkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHBjdF95ZXMpKSArDQogIGdlb21fbGluZShkYXRhID0gYnlfeWVhciwgbHR5ID0gMSwgc2l6ZSA9IDEuOCwgYWxwaGEgPSAwLjMpICsNCiAgZ2VvbV9saW5lKGFlcyhjb2wgPSBjb250aW5lbnQpLCBzaXplID0gMC45KSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArDQogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICBleHBhbmRfbGltaXRzKHkgPSAwKSsNCiAgbGFicyh0aXRsZSA9ICIlIHllcyBieSBjb250aW5lbnRzIG92ZXIgdGhlIHllYXJzIHdpdGggd29ybGQgYXZlcmFnZSIsDQogICAgICAgY2FwdGlvbiA9ICJjcmVhdGVkIGJ5IFZpU2EiKQ0KYGBgDQoNCiMjIGdkcCBmcm9tIFdESQ0KDQpgYGB7cn0NCmxpYnJhcnkoV0RJKQ0KYGBgDQoNCmBgYHtyfQ0KY291bnRyeV9pbmNvbWVzIDwtIFdESShpbmRpY2F0b3IgPSBjKGdkcF9wZXJfY2FwaXRhID0gIk5ZLkdEUC5QQ0FQLlBQLktEIiwNCiAgICAgICAgICAgICAgICAgIHBvcCA9ICJTUC5QT1AuVE9UTCIpLA0KICAgIHN0YXJ0ID0gMjAxOSwgZW5kID0gMjAxOSwgZXh0cmEgPSBUUlVFKSAlPiUgDQogIGFzX3RpYmJsZSgpICU+JSANCiAgc2VsZWN0KGNvdW50cnlfY29kZSA9IGlzbzJjLCBpbmNvbWUsIGdkcF9wZXJfY2FwaXRhLCBwb3ApICU+JSANCiAgZmlsdGVyKCFpcy5uYShpbmNvbWUpKSAlPiUgDQogIG11dGF0ZShpbmNvbWUgPSBmY3RfcmVsZXZlbChpbmNvbWUsICJMb3cgaW5jb21lIiwgIkxvd2VyIG1pZGRsZSBpbmNvbWUiLCAiVXBwZXIgbWlkZGxlIGluY29tZSIpKQ0KDQpjb3VudHJ5X2luY29tZXMNCmBgYA0KDQpgYGB7cn0NCnBsb3RfYnkgPC0gZnVuY3Rpb24odGJsLCBjYXRlZ29yeSl7DQogICAgdGJsICU+JQ0KICAgIGZpbHRlcighaXMubmEoe3tjYXRlZ29yeX19KSkgJT4lIA0KICAgIG11dGF0ZShjYXRlZ29yeSA9IGZjdF9yZW9yZGVyKHt7Y2F0ZWdvcnl9fSwgcGN0X3llcykpICU+JSANCiAgICANCiAgICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcGN0X3llcykpICsNCiAgICAjIGdlb21fbGluZShkYXRhID0gYnlfeWVhciwgbHR5ID0gMSwgc2l6ZSA9IDEuOCwgYWxwaGEgPSAwLjMpICsNCiAgICBnZW9tX2xpbmUoYWVzKGNvbCA9IHt7Y2F0ZWdvcnl9fSksIHNpemUgPSAwLjkpICsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkgKw0KICAgIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKw0KICAgIGV4cGFuZF9saW1pdHMoeSA9IDApKw0KICAgIGxhYnModGl0bGUgPSAiJSB5ZXMgYnkgY291bnRyaWVzIG92ZXIgdGhlIHllYXJzIHdpdGggd29ybGQgYXZlcmFnZSIsDQogICAgICAgY2FwdGlvbiA9ICJjcmVhdGVkIGJ5IFZpU2EiKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KdW52b3RlcyAlPiUgDQogIGlubmVyX2pvaW4oY291bnRyeV9pbmNvbWVzLCBieSA9ICJjb3VudHJ5X2NvZGUiKSAlPiUgDQogIGdyb3VwX2J5KGluY29tZSwNCiAgICAgICAgICAgeWVhciA9IHllYXIoZGF0ZSkpICU+JSANCiAgc3VtbWFyaXplX3ZvdGVzKCkgJT4lIA0KICBwbG90X2J5KGluY29tZSkNCmBgYA0KDQojIyBDb3JyZWxhdGlvbiBidyBjb3VudHJpZXMNCg0KYGBge3J9DQp1bnZvdGVzICU+JSANCiAgZmlsdGVyKGNvdW50cnkgJWluJSBjKCJJbmRpYSIsIlJ1c3NpYSIpKSAlPiUgDQogIHNlbGVjdChyY2lkLCBjb3VudHJ5LCB2b3RlX251bWJlcikgJT4lIA0KICBzcHJlYWQoY291bnRyeSwgdm90ZV9udW1iZXIsIGZpbGwgPSAwKQ0KYGBgDQoNCmBgYHtyfQ0KdW52b3RlcyAlPiUgDQogIGZpbHRlcihjb3VudHJ5ICVpbiUgYygiSW5kaWEiLCJDYW5hZGEiKSkgJT4lIA0KICBzZWxlY3QocmNpZCwgY291bnRyeSwgdm90ZV9udW1iZXIpICU+JSANCiAgc3ByZWFkKGNvdW50cnksIHZvdGVfbnVtYmVyLCBmaWxsID0gMCkgJT4lIA0KICBzdW1tYXJpemUoY29ycmVsYXRpb24gPSBjb3IoLltbMl1dLC5bWzNdXSkpDQpgYGANCg0KYGBge3J9DQpjb3JyX2ZuIDwtIGZ1bmN0aW9uKGNvdW50cmllc19zZWwgPSBjKCJJbmRpYSIsICJVbml0ZWQgU3RhdGVzIikpew0KICB1bnZvdGVzICU+JSANCiAgZmlsdGVyKGNvdW50cnkgJWluJSBjb3VudHJpZXNfc2VsKSAlPiUgDQogIHNlbGVjdChyY2lkLCBjb3VudHJ5LCB2b3RlX251bWJlcikgJT4lIA0KICBzcHJlYWQoY291bnRyeSwgdm90ZV9udW1iZXIsIGZpbGwgPSAwKSAlPiUgDQogIHN1bW1hcml6ZShjb3JyZWxhdGlvbiA9IGNvciguW1syXV0sLltbM11dKSkNCn0NCmBgYA0KDQpgYGB7cn0NCmNvcnJfZm4oYygiSW5kaWEiLCJQYWtpc3RhbiIpKQ0KYGBgDQoNCiMjIyB3aWR5ciBwYWlyd2lzZSBjb3JyDQoNCmBgYHtyfQ0KbGlicmFyeSh3aWR5cikNCmBgYA0KDQpgYGB7cn0NCnVudm90ZXMgJT4lIA0KICBwYWlyd2lzZV9jb3IoaXRlbSA9IGNvdW50cnksIGZlYXR1cmUgPSAgcmNpZCwgdmFsdWUgPSAgdm90ZV9udW1iZXIsIHNvcnQgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5Z3JhcGgpDQpsaWJyYXJ5KGdncmFwaCkNCmBgYA0KDQp0aWR5Z3JhcGggJiBnZ3JhcGggZnJvbTogPGh0dHBzOi8veW91dHUuYmUvbUFwbng1Tkp3UUE/dD04NjI+DQoNCmBgYHtyIGVjaG89RkFMU0V9DQojIHVudm90ZXMgJT4lIA0KIyAgIHBhaXJ3aXNlX2NvcihpdGVtID0gY291bnRyeSwgZmVhdHVyZSA9ICByY2lkLCANCiMgICAgICAgICAgICAgICAgdmFsdWUgPSAgdm90ZV9udW1iZXIsIHNvcnQgPSBUUlVFKSAlPiUgDQojICAgYXNfdGJsX2dyYXBoKCkgJT4lIA0KIyAgIGlubmVyX2pvaW4oeSA9ICh1bnZvdGVzICU+JSBjb3VudChjb3VudHJ5KSksIGJ5ID0gYyhuYW1lID0gImNvdW50cnkiKSkgJT4lIA0KIyAgIGdncmFwaChsYXlvdXQgPSAiZnIiKSArDQojICAgZ2VvbV9lZGdlX2xpbmsoYWVzKGVkZ2VfYWxwaGEgPSBjb3JyZWxhdGlvbikpICsNCiMgICBnZW9tX25vZGVfcG9pbnQoYWVzKHNpemUgPSBuKSkgKw0KIyAgIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCBjaGVja19vdmVybGFwID0gVFJVRSwNCiMgICAgICAgICAgICAgICAgICB2anVzdCA9MSwgaGp1c3QgPTEsIHNpemUgPSAzKSArDQojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCmBgYHtyfQ0KdW52b3RlcyAlPiUgDQogIHBhaXJ3aXNlX2NvcihpdGVtID0gY291bnRyeSwgZmVhdHVyZSA9ICByY2lkLCANCiAgICAgICAgICAgICAgIHZhbHVlID0gIHZvdGVfbnVtYmVyLCBzb3J0ID0gVFJVRSkgJT4lIA0KICBmaWx0ZXIoaXRlbTEgPT0gIkluZGlhIikNCmBgYA0KDQpgYGB7cn0NCmNvcnJfdGJsIDwtIHVudm90ZXMgJT4lIA0KICBwYWlyd2lzZV9jb3IoaXRlbSA9IGNvdW50cnksIGZlYXR1cmUgPSAgcmNpZCwgDQogICAgICAgICAgICAgICB2YWx1ZSA9ICB2b3RlX251bWJlciwgc29ydCA9IFRSVUUpICU+JSANCiAgIyBmaWx0ZXIoaXRlbTEgPT0gIkluZGlhIikgJT4lIA0KICANCiAgbGVmdF9qb2luKHkgPSAodW52b3RlcyAlPiUgDQogICAgICAgICAgICAgICAgICBtdXRhdGUoY29udGluZW50ID0gY291bnRyeWNvZGUoY291bnRyeV9jb2RlLCAiaXNvMmMiLCAiY29udGluZW50IikpICU+JSANCiAgICAgICAgICAgICAgICAgIHNlbGVjdChjb3VudHJ5LCBjb250aW5lbnQpICU+JSANCiAgICAgICAgICAgICAgICAgIGRpc3RpbmN0KCkpLA0KICAgICAgICAgICAgYnkgPSBjKCJpdGVtMiIgPSAiY291bnRyeSIpKSAlPiUgDQogIHJlbmFtZShjb250aW5lbnRfaXRlbTIgPSBjb250aW5lbnQpDQoNCmNvcnJfdGJsDQpgYGANCg0KYGBge3J9DQpjb3JyX3RibCAlPiUgDQogIGZpbHRlcihpdGVtMSA9PSAiSW5kaWEiLA0KICAgICAgICAgIWlzLm5hKGNvbnRpbmVudF9pdGVtMikpICU+JSANCiAgYXJyYW5nZShkZXNjKGNvcnJlbGF0aW9uKSkgJT4lIA0KICBzbGljZShjKDE6MTUsIChuKCktIDA6MTUpICkpICU+JSANCiAgbXV0YXRlKGl0ZW0yID0gc3RyX3dyYXAoaXRlbTIsIHdpZHRoID0gMjUpKSAlPiUgDQogIA0KICBnZ3Bsb3QoYWVzKHggPSBjb3JyZWxhdGlvbiwgDQogICAgICAgICAgICAgeSA9IHJlb3JkZXJfd2l0aGluKGl0ZW0yLCBieSA9IGNvcnJlbGF0aW9uLCB3aXRoaW4gPSBjb250aW5lbnRfaXRlbTIpLCANCiAgICAgICAgICAgICBjb2wgPSBjb250aW5lbnRfaXRlbTIpKSArDQogIGdlb21fcG9pbnQoc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsdHkgPSAyLCBzaXplID0gMC45LCBjb2wgPSAidG9tYXRvIikgKw0KICBmYWNldF93cmFwKH5jb250aW5lbnRfaXRlbTIsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIHNjYWxlX3lfcmVvcmRlcmVkKCkgKw0KICBsYWJzKHRpdGxlID0gIlRvcCAmIGJvdHRvbSBjb3JyZWxhdGVkIGNvdW50cmllcyBpbiB2b3RpbmcgaW4gVU4gdG8gSW5kaWEiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpICsNCiAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KDQojIyMgY29ycmVsYXRpb24gb2YgY291bnRyaWVzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQ0KDQpgYGB7cn0NCnRvcF9jb3JyX2NvdW50cmllc193aXRoIDwtIGZ1bmN0aW9uKGNvdW50cnlfc2VsZWN0ZWQgPSAiSW5kaWEiLCB0b3Bfbl9ib3R0b20gPSAxNSl7DQogIGNvcnJfdGJsICU+JSANCiAgZmlsdGVyKGl0ZW0xID09IGNvdW50cnlfc2VsZWN0ZWQsDQogICAgICAgICAhaXMubmEoY29udGluZW50X2l0ZW0yKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoY29ycmVsYXRpb24pKSAlPiUgDQogIHNsaWNlKGMoMTp0b3Bfbl9ib3R0b20sIChuKCktIDA6dG9wX25fYm90dG9tKSApKSAlPiUgDQogIG11dGF0ZShpdGVtMiA9IHN0cl93cmFwKGl0ZW0yLCB3aWR0aCA9IDI1KSkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gY29ycmVsYXRpb24sIA0KICAgICAgICAgICAgIHkgPSByZW9yZGVyX3dpdGhpbihpdGVtMiwgYnkgPSBjb3JyZWxhdGlvbiwgd2l0aGluID0gY29udGluZW50X2l0ZW0yKSwNCiAgICAgICAgICAgICBjb2wgPSBjb3JyZWxhdGlvbiA+IDApKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fZXJyb3JiYXJoKGhlaWdodCA9IDAsIGFlcyh4bWluID0gY29ycmVsYXRpb24sIHhtYXggPSAwKSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsdHkgPSAyLCBzaXplID0gMC45LCBjb2wgPSAibWlkbmlnaHRibHVlIikgKw0KICBmYWNldF93cmFwKH5jb250aW5lbnRfaXRlbTIsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIHNjYWxlX3lfcmVvcmRlcmVkKCkgKw0KICBleHBhbmRfbGltaXRzKHggPSAwLjgpICsNCiAgbGFicyh0aXRsZSA9IGdsdWUoIlRvcCAmIGJvdHRvbSBjb3JyZWxhdGVkIGNvdW50cmllcyBpbiB2b3RpbmcgaW4gVU4gd2l0aCA8aT57Y291bnRyeV9zZWxlY3RlZH08L2k+IiksDQogICAgICAgeSA9ICIiLA0KICAgICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikgKw0KICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgcGxvdC50aXRsZSA9IGdndGV4dDo6ZWxlbWVudF9tYXJrZG93bigpLA0KICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KfQ0KYGBgDQoNCiMjIyMgSW5kaWENCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCnRvcF9jb3JyX2NvdW50cmllc193aXRoKHRvcF9uX2JvdHRvbSA9IDIwKQ0KYGBgDQoNCiMjIyMgRnJhbmNlDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9DQp0b3BfY29ycl9jb3VudHJpZXNfd2l0aCgiRnJhbmNlIiwgdG9wX25fYm90dG9tID0gMjApDQpgYGANCg0KIyMjIyBQYWtpc3Rhbg0KDQpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQ0KdG9wX2NvcnJfY291bnRyaWVzX3dpdGgoIlBha2lzdGFuIiwgdG9wX25fYm90dG9tID0gMjApDQpgYGANCg0KIyMjIyBSdXNzaWENCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCnRvcF9jb3JyX2NvdW50cmllc193aXRoKCJSdXNzaWEiLCB0b3Bfbl9ib3R0b20gPSAyMCkNCmBgYA0KDQojIyMjIENoaW5hDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9DQp0b3BfY29ycl9jb3VudHJpZXNfd2l0aCgiQ2hpbmEiLCB0b3Bfbl9ib3R0b20gPSAyMCkNCmBgYA0KDQojIyMjIEF1c3RyYWxpYQ0KDQpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQ0KdG9wX2NvcnJfY291bnRyaWVzX3dpdGgoIkF1c3RyYWxpYSIsIHRvcF9uX2JvdHRvbSA9IDIwKQ0KYGBgDQoNCiMjIyMgVW5pdGVkIEFyYWIgRW1pcmF0ZXMNCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCnRvcF9jb3JyX2NvdW50cmllc193aXRoKCJVbml0ZWQgQXJhYiBFbWlyYXRlcyIsIHRvcF9uX2JvdHRvbSA9IDIwKQ0KYGBgDQoNCiMjIyMgU2F1ZGkgQXJhYmlhDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9DQp0b3BfY29ycl9jb3VudHJpZXNfd2l0aCgiU2F1ZGkgQXJhYmlhIiwgdG9wX25fYm90dG9tID0gMjApDQpgYGANCg0KIyMjIyBJc3JhZWwNCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCnRvcF9jb3JyX2NvdW50cmllc193aXRoKCJJc3JhZWwiLCB0b3Bfbl9ib3R0b20gPSAyMCkNCmBgYA0KDQojIyMjIFR1cmtleQ0KDQpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQ0KdG9wX2NvcnJfY291bnRyaWVzX3dpdGgoIlR1cmtleSIsIHRvcF9uX2JvdHRvbSA9IDIwKQ0KYGBgDQoNCiMjIyMgVVMNCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCnRvcF9jb3JyX2NvdW50cmllc193aXRoKCJVbml0ZWQgU3RhdGVzIiwgdG9wX25fYm90dG9tID0gMjApDQpgYGANCg0KIyMjIENvb3JlbGF0aW9uIGRpZmZlcmVuY2VzDQoNCmBgYHtyfQ0KY29ycl90YmwgJT4lIA0KICBncm91cF9ieShjb3VudHJ5ID0gaXRlbTEpICU+JSANCiAgZmlsdGVyKCFpcy5uYShjb3JyZWxhdGlvbikpICU+JSANCiAgbXV0YXRlX2lmKGlzLmNoYXJhY3RlciwgYXNfZmFjdG9yKSAlPiUgI3N1bW1hcnkoKQ0KICBzdW1tYXJpc2UobWVkaWFuX2NvcnIgPSBtZWRpYW4oY29ycmVsYXRpb24pLA0KICAgICAgICAgICAgbWVhbl9jb3JyID0gbWVhbihjb3JyZWxhdGlvbikpICU+JSANCiAgYXJyYW5nZShkZXNjKG1lZGlhbl9jb3JyKSkNCmBgYA0KDQpgYGB7cn0NCmNvcnJfdGJsIDwtIGNvcnJfdGJsICU+JSANCiAgc2VsZWN0KC1jb250aW5lbnRfaXRlbTIpICU+JSANCiAgDQogIG11dGF0ZShjb250aW5lbnQxID0gY291bnRyeWNvZGUoaXRlbTEsICJjb3VudHJ5Lm5hbWUiLCAiY29udGluZW50IiksDQogICAgICAgICBjb250aW5lbnQyID0gY291bnRyeWNvZGUoaXRlbTIsICJjb3VudHJ5Lm5hbWUiLCAiY29udGluZW50IikpDQoNCmNvcnJfdGJsDQpgYGANCg0KIyMjIEludGVyY29udGluZW50IGNvcnJlbGF0aW9uDQoNCmBgYHtyfQ0KY29ycl90YmwgJT4lIA0KICBuYS5vbWl0KCkgJT4lDQogIA0KICBncm91cF9ieShjb250aW5lbnQxLCBjb250aW5lbnQyKSAlPiUgDQogIHN1bW1hcmlzZShhdmdfY29yciA9IG1lYW4oY29ycmVsYXRpb24pKSAlPiUNCiAgYXJyYW5nZShkZXNjKGF2Z19jb3JyKSkNCmBgYA0KDQpgYGB7cn0NCmludGVyY29udGluZW50X2NvcnIgPC0gY29ycl90YmwgJT4lIA0KICBuYS5vbWl0KCkgJT4lIA0KICANCiAgZmlsdGVyKGNvbnRpbmVudDEgPT0gY29udGluZW50MikgJT4lIA0KICBncm91cF9ieShpdGVtMSkgJT4lIA0KICBzdW1tYXJpc2UoYXZnX2ludGVyY29udGluZW50X2NvcnJlbGF0aW9uID0gbWVhbihjb3JyZWxhdGlvbikpICU+JSANCiAgYXJyYW5nZShkZXNjKGF2Z19pbnRlcmNvbnRpbmVudF9jb3JyZWxhdGlvbikpDQoNCmludGVyY29udGluZW50X2NvcnINCmBgYA0KDQp0YWl3YW4gJiBpc3JhZWwgaGF2ZSBsZWFzdCBjb3JyIHdoaWNoIGlzIGluIG5lZ2F0aXZlDQoNCmBgYHtyfQ0KbGlicmFyeShwbG90bHkpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3RseSh3b3JsZF9kYXRhICU+JQ0KICBsZWZ0X2pvaW4oKGludGVyY29udGluZW50X2NvcnIgJT4lIA0KICAgICAgICAgICAgICAgbXV0YXRlKGNvdW50cnlfY29kZSA9IGNvdW50cnljb2RlKGl0ZW0xLCAiY291bnRyeS5uYW1lIiwgImlzbzJjIikpDQogICAgICAgICAgICAgKSwgDQogICAgICAgICAgICBieSA9IGMoImNvdW50cnlfY29kZSIpKSAlPiUgDQogIA0KICBnZ3Bsb3QoYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwLCANCiAgICAgICAgICAgICBmaWxsID0gYXZnX2ludGVyY29udGluZW50X2NvcnJlbGF0aW9uLCBsYWJlbCA9IGl0ZW0xKSkgKw0KICBnZW9tX3BvbHlnb24oKSArDQogIHRoZW1lX21hcCgpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93ID0gInJlZCIsIGhpZ2ggPSAiYmx1ZSIsIA0KICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IC0wLjEpICsNCiAgbGFicyhmaWxsID0gImF2ZyBpbnRlcmNvbnRpbmVudCBjb3JyZWxhdGlvbiIsDQogICAgICAgY2FwdGlvbiA9ICJjcmVhdGVkIGJ5IFZpU2EiKSkNCmBgYA0KDQpib3RoIHRhaXdhbiAmIGlzcmFlbCBhcmUgaGFyZCB0byBiZSBzZWVuIGluIG1hcA0KDQojIyB0ZXh0IChpc3N1ZXMpDQoNCmBgYHtyfQ0KdHQkaXNzdWVzICU+JSANCiAgY291bnQoaXNzdWUpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl0ZXh0KQ0KYGBgDQoNCmBgYHtyfQ0KdHQkcm9sbF9jYWxscyAlPiUgDQogIGZpbHRlcighaXMubmEoc2hvcnQpKSAlPiUgDQogIHVubmVzdF90b2tlbnMod29yZCwgc2hvcnQpICU+JSANCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gIndvcmQiKSAlPiUgDQogIGNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0KcmNfd29yZHMgPC0gdHQkcm9sbF9jYWxscyAlPiUgDQogIGZpbHRlcighaXMubmEoc2hvcnQpKSAlPiUgDQogIHVubmVzdF90b2tlbnMod29yZCwgc2hvcnQpICU+JSANCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gIndvcmQiKSAlPiUgDQogIHNlbGVjdChyY2lkLCB3b3JkKQ0KDQpyY193b3Jkcw0KYGBgDQoNCmBgYHtyfQ0KdW52b3RlcyAlPiUgDQogIGlubmVyX2pvaW4ocmNfd29yZHMsIGJ5ID0gInJjaWQiKQ0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9DQp1bnZvdGVzICU+JSANCiAgaW5uZXJfam9pbihyY193b3JkcywgYnkgPSAicmNpZCIpICU+JSANCiAgZmlsdGVyKGNvdW50cnkgPT0gIlVuaXRlZCBTdGF0ZXMiKSAlPiUgDQogIGdyb3VwX2J5KHdvcmQpICU+JSANCiAgc3VtbWFyaXplX3ZvdGVzKG1pbl92b3RlcyA9IDEwMCkgJT4lIA0KICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHBjdF95ZXMpKSAlPiUgDQogIA0KICBnZ3Bsb3QoYWVzKHBjdF95ZXMsIHdvcmQpKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkrDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSANCmBgYA0KDQojIyMgeWVzIHZvdGUgd29yZHMgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9DQoNCmBgYHtyIH0NCndvcmRzX3llc192b3RlcyA8LSBmdW5jdGlvbihjb3VudHJ5X3NlbGVjdGVkID0gIkluZGlhIiwgbWluX3ZvdGVfbGltaXQgPSAxMDApew0KICAgIHVudm90ZXMgJT4lIA0KICAgIGlubmVyX2pvaW4ocmNfd29yZHMsIGJ5ID0gInJjaWQiKSAlPiUgDQogICAgZmlsdGVyKGNvdW50cnkgPT0gY291bnRyeV9zZWxlY3RlZCkgJT4lIA0KICAgIGdyb3VwX2J5KHdvcmQpICU+JSANCiAgICBzdW1tYXJpemVfdm90ZXMobWluX3ZvdGVzID0gbWluX3ZvdGVfbGltaXQpICU+JSANCiAgICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHBjdF95ZXMpKSAlPiUgDQogICAgDQogICAgZ2dwbG90KGFlcyhwY3RfeWVzLCB3b3JkKSkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkrDQogICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF9tYXJrZG93bigpKSArDQogICAgbGFicyh0aXRsZSA9IGdsdWUoIk1vc3QgY29tbW9uIHdvcmRzIGZvciB5ZXMgdm90ZXMgYnkgPGk+e2NvdW50cnlfc2VsZWN0ZWR9PC9pPiIpKQ0KfQ0KYGBgDQoNCiMjIyMgSW5kaWENCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCndvcmRzX3llc192b3RlcygpIA0KYGBgDQoNCiMjIyMgUGFraXN0YW4NCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCndvcmRzX3llc192b3RlcygiUGFraXN0YW4iKSANCmBgYA0KDQojIyMjIElzcmFlbA0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0Kd29yZHNfeWVzX3ZvdGVzKCJJc3JhZWwiKSANCmBgYA0KDQojIyMgcGFpciBjb3VudHJ5IHllcyB2b3RlIHdvcmRzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQ0KDQpgYGB7ciB9DQp3b3Jkc195ZXNfdm90ZXNfbXVsdGkgPC0gZnVuY3Rpb24oY291bnRyeV9zZWxlY3RlZCA9IGMoIkluZGlhIiwiUnVzc2lhIiksIG1pbl92b3RlX2xpbWl0ID0gMTAwKXsNCiAgICB1bnZvdGVzICU+JSANCiAgICBpbm5lcl9qb2luKHJjX3dvcmRzLCBieSA9ICJyY2lkIikgJT4lIA0KICAgIGZpbHRlcihjb3VudHJ5ICVpbiUgY291bnRyeV9zZWxlY3RlZCkgJT4lIA0KICAgIGdyb3VwX2J5KHdvcmQsIGNvdW50cnkpICU+JSANCiAgICBzdW1tYXJpemVfdm90ZXMobWluX3ZvdGVzID0gbWluX3ZvdGVfbGltaXQpICU+JSANCiAgICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHBjdF95ZXMpKSAlPiUgDQogICAgDQogICAgZ2dwbG90KGFlcyhwY3RfeWVzLCB3b3JkLCBjb2wgPSBjb3VudHJ5KSkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkrDQogICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF9tYXJrZG93bigpKSAjKw0KICAgICMgbGFicyh0aXRsZSA9IGdsdWUoIk1vc3QgY29tbW9uIHdvcmRzIGZvciB5ZXMgdm90ZXMgYnkgPGk+e2NvdW50cnlfc2VsZWN0ZWR9PC9pPiIpKQ0KfQ0KYGBgDQoNCiMjIyMgSW5kL1J1cw0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0Kd29yZHNfeWVzX3ZvdGVzX211bHRpKCkNCmBgYA0KDQojIyMjIEluZC9QYWsNCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCndvcmRzX3llc192b3Rlc19tdWx0aShjKCJJbmRpYSIsIlBha2lzdGFuIikgKQ0KYGBgDQoNCiMjIyMgSW5kL0NoaQ0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0Kd29yZHNfeWVzX3ZvdGVzX211bHRpKGMoIkluZGlhIiwiQ2hpbmEiKSApDQpgYGANCg0KIyMjIERpZmYgb2YgeWVzIHZvdGVzDQoNCmBgYHtyIH0NCndvcmRzX3llc192b3Rlc19tdWx0aV9kaWZmIDwtIGZ1bmN0aW9uKGNvdW50cnlfc2VsZWN0ZWQgPSBjKCJJbmRpYSIsIlJ1c3NpYSIpLCBtaW5fdm90ZV9saW1pdCA9IDEwMCl7DQogICAgdW52b3RlcyAlPiUgDQogICAgaW5uZXJfam9pbihyY193b3JkcywgYnkgPSAicmNpZCIpICU+JSANCiAgICBmaWx0ZXIoY291bnRyeSAlaW4lIGNvdW50cnlfc2VsZWN0ZWQpICU+JSANCiAgICBncm91cF9ieSh3b3JkLCBjb3VudHJ5KSAlPiUgDQogICAgc3VtbWFyaXplX3ZvdGVzKG1pbl92b3RlcyA9IG1pbl92b3RlX2xpbWl0KSAlPiUgDQogICAgbXV0YXRlKHdvcmQgPSBmY3RfcmVvcmRlcih3b3JkLCBwY3RfeWVzLCBmdW5jdGlvbih4KSBtYXgoeCkgLSBtaW4oeCkpKSAlPiUgDQogICAgDQogICAgZ2dwbG90KGFlcyhwY3RfeWVzLCB3b3JkLCBjb2wgPSBjb3VudHJ5KSkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkrDQogICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICsNCiAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF9tYXJrZG93bigpKSAjKw0KICAgICMgbGFicyh0aXRsZSA9IGdsdWUoIk1vc3QgY29tbW9uIHdvcmRzIGZvciB5ZXMgdm90ZXMgYnkgPGk+e2NvdW50cnlfc2VsZWN0ZWR9PC9pPiIpKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0Kd29yZHNfeWVzX3ZvdGVzX211bHRpX2RpZmYoKQ0KYGBgDQoNCiMjIE5ncmFtcw0KDQojIyMgYmkgZ3JhbXMNCg0KYGBge3J9DQp0dCRyb2xsX2NhbGxzICU+JSANCiAgZmlsdGVyKCFpcy5uYShzaG9ydCkpICU+JSANCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCBzaG9ydCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9MikgJT4lIA0KICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkNCmBgYA0KDQpgYGB7cn0NCmJpX2dyYW1zIDwtIHR0JHJvbGxfY2FsbHMgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNob3J0KSkgJT4lIA0KICB1bm5lc3RfdG9rZW5zKHdvcmQsIHNob3J0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0yKSAlPiUgDQogIG5hLm9taXQoKSAlPiUgDQogIGFudGlfam9pbihzdG9wX3dvcmRzLCBieSA9ICJ3b3JkIikgJT4lIA0KICBzZWxlY3QocmNpZCwgd29yZCkNCg0KYmlfZ3JhbXMNCmBgYA0KDQpgYGB7cn0NCnVudm90ZXMgJT4lIA0KICAgIGlubmVyX2pvaW4oYmlfZ3JhbXMsIGJ5ID0gInJjaWQiKSAlPiUgDQogICAgZmlsdGVyKGNvdW50cnkgPT0gIkluZGlhIikgJT4lIA0KICAgIGdyb3VwX2J5KHdvcmQpICU+JSANCiAgICBzdW1tYXJpemVfdm90ZXMobWluX3ZvdGVzID0gMjApICU+JSANCiAgICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHBjdF95ZXMpKSAlPiUgDQogICAgDQogICAgZ2dwbG90KGFlcyhwY3RfeWVzLCB3b3JkKSkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkrDQogICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpDQpgYGANCg0KIyMjIHllcyB2b3RlIGJpZ3JhbXMgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9DQoNCmBgYHtyIH0NCmJpZ3JhbXNfeWVzX3ZvdGVzX211bHRpIDwtIGZ1bmN0aW9uKGNvdW50cnlfc2VsZWN0ZWQgPSBjKCJJbmRpYSIsIlJ1c3NpYSIpLCBtaW5fdm90ZV9saW1pdCA9IDIwKQ0KICB7DQogICAgdW52b3RlcyAlPiUgDQogICAgaW5uZXJfam9pbihiaV9ncmFtcywgYnkgPSAicmNpZCIpICU+JSANCiAgICBmaWx0ZXIoY291bnRyeSAlaW4lIGNvdW50cnlfc2VsZWN0ZWQpICU+JSANCiAgICBncm91cF9ieSh3b3JkLCBjb3VudHJ5KSAlPiUgDQogICAgc3VtbWFyaXplX3ZvdGVzKG1pbl92b3RlcyA9IG1pbl92b3RlX2xpbWl0KSAlPiUgDQogICAgbXV0YXRlKHdvcmQgPSBmY3RfcmVvcmRlcih3b3JkLCBwY3RfeWVzKSkgJT4lIA0KICAgIA0KICAgIGdncGxvdChhZXMocGN0X3llcywgd29yZCwgY29sID0gY291bnRyeSkpICsNCiAgICBnZW9tX3BvaW50KGFlcyhzaXplID0gbl92b3RlcykpKw0KICAgIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSAjKw0KICAgICMgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfbWFya2Rvd24oKSkgKw0KICAgICMgbGFicyh0aXRsZSA9IGdsdWUoIk1vc3QgY29tbW9uIGJpIGdyYW1zIGZvciB5ZXMgdm90ZXMgYnkgPGk+e2NvdW50cnlfc2VsZWN0ZWR9PC9pPiIpKQ0KfQ0KYGBgDQoNCiMjIyMgSW5kL1J1cw0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0KYmlncmFtc195ZXNfdm90ZXNfbXVsdGkoKQ0KYGBgDQoNCiMjIyMgSW5kL1Bhaw0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0KYmlncmFtc195ZXNfdm90ZXNfbXVsdGkoYygiSW5kaWEiLCJQYWtpc3RhbiIpKQ0KYGBgDQoNCiMjIyMgSW5kL1Bhaw0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0KYmlncmFtc195ZXNfdm90ZXNfbXVsdGkoYygiSW5kaWEiLCJVbml0ZWQgU3RhdGVzIikpDQpgYGANCg0KIyMjIyBJbmQvRnJhDQoNCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9DQpiaWdyYW1zX3llc192b3Rlc19tdWx0aShjKCJJbmRpYSIsIkZyYW5jZSIpKQ0KYGBgDQoNCiMjIyB5ZXMgdm90ZSBiaWdyYW1zIGRpZmYgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9DQoNCmBgYHtyIH0NCmJpZ3JhbXNfeWVzX3ZvdGVzX211bHRpX2RpZmYgPC0gZnVuY3Rpb24oY291bnRyeV9zZWxlY3RlZCA9IGMoIkluZGlhIiwiUnVzc2lhIiksIG1pbl92b3RlX2xpbWl0ID0gMjApDQogIHsNCiAgICB1bnZvdGVzICU+JSANCiAgICBpbm5lcl9qb2luKGJpX2dyYW1zLCBieSA9ICJyY2lkIikgJT4lIA0KICAgIGZpbHRlcihjb3VudHJ5ICVpbiUgY291bnRyeV9zZWxlY3RlZCkgJT4lIA0KICAgIGdyb3VwX2J5KHdvcmQsIGNvdW50cnkpICU+JSANCiAgICBzdW1tYXJpemVfdm90ZXMobWluX3ZvdGVzID0gbWluX3ZvdGVfbGltaXQpICU+JSANCiAgICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHBjdF95ZXMsIGZ1bmN0aW9uKHgpIG1heCh4KSAtIG1pbih4KSkpICU+JSANCiAgICANCiAgICBnZ3Bsb3QoYWVzKHBjdF95ZXMsIHdvcmQsIGNvbCA9IGNvdW50cnkpKSArDQogICAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IG5fdm90ZXMpKSsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkgIysNCiAgICAjIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X21hcmtkb3duKCkpICsNCiAgICAjIGxhYnModGl0bGUgPSBnbHVlKCJNb3N0IGNvbW1vbiBiaSBncmFtcyBmb3IgeWVzIHZvdGVzIGJ5IDxpPntjb3VudHJ5X3NlbGVjdGVkfTwvaT4iKSkNCn0NCmBgYA0KDQojIyMjIEluZC9SdXMNCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCmJpZ3JhbXNfeWVzX3ZvdGVzX211bHRpX2RpZmYoKQ0KYGBgDQoNCiMjIyMgSW5kL1Bhaw0KDQpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQ0KYmlncmFtc195ZXNfdm90ZXNfbXVsdGlfZGlmZihjKCJJbmRpYSIsIlBha2lzdGFuIikpDQpgYGANCg0KIyMjIHF1YWQgZ3JhbXMNCg0KYGBge3J9DQp0dCRyb2xsX2NhbGxzICU+JSANCiAgZmlsdGVyKCFpcy5uYShzaG9ydCkpICU+JSANCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCBzaG9ydCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9NCkgJT4lIA0KICBuYS5vbWl0KCkgJT4lIA0KICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkNCmBgYA0KDQpgYGB7cn0NCnF1YWRfZ3JhbXMgPC0gdHQkcm9sbF9jYWxscyAlPiUgDQogIGZpbHRlcighaXMubmEoc2hvcnQpKSAlPiUgDQogIHVubmVzdF90b2tlbnMod29yZCwgc2hvcnQsIHRva2VuID0gIm5ncmFtcyIsIG4gPTQpICU+JSANCiAgbmEub21pdCgpICU+JSANCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gIndvcmQiKSAlPiUgDQogIHNlbGVjdChyY2lkLCB3b3JkKQ0KDQpxdWFkX2dyYW1zDQpgYGANCg0KIyMjIHllcyB2b3RlIHF1YWRncmFtcyB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30NCg0KYGBge3IgfQ0KcXVhZGdyYW1zX3llc192b3Rlc19tdWx0aSA8LSBmdW5jdGlvbihjb3VudHJ5X3NlbGVjdGVkID0gYygiSW5kaWEiLCJSdXNzaWEiKSwgbWluX3ZvdGVfbGltaXQgPSA1KQ0KICB7DQogICAgdW52b3RlcyAlPiUgDQogICAgaW5uZXJfam9pbihxdWFkX2dyYW1zLCBieSA9ICJyY2lkIikgJT4lIA0KICAgIGZpbHRlcihjb3VudHJ5ICVpbiUgY291bnRyeV9zZWxlY3RlZCkgJT4lIA0KICAgIGdyb3VwX2J5KHdvcmQsIGNvdW50cnkpICU+JSANCiAgICBzdW1tYXJpemVfdm90ZXMobWluX3ZvdGVzID0gbWluX3ZvdGVfbGltaXQpICU+JSANCiAgICBtdXRhdGUod29yZCA9IGZjdF9yZW9yZGVyKHdvcmQsIHBjdF95ZXMpKSAlPiUgDQogICAgDQogICAgZ2dwbG90KGFlcyhwY3RfeWVzLCB3b3JkLCBjb2wgPSBjb3VudHJ5KSkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuX3ZvdGVzKSkrDQogICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQpICMrDQogICAgIyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF9tYXJrZG93bigpKSArDQogICAgIyBsYWJzKHRpdGxlID0gZ2x1ZSgiTW9zdCBjb21tb24gYmkgZ3JhbXMgZm9yIHllcyB2b3RlcyBieSA8aT57Y291bnRyeV9zZWxlY3RlZH08L2k+IikpDQp9DQpgYGANCg0KIyMjIyBJbmQvUnVzDQoNCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9DQpxdWFkZ3JhbXNfeWVzX3ZvdGVzX211bHRpKCkNCmBgYA0KDQojIyMjIEluZC9DYW4NCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCnF1YWRncmFtc195ZXNfdm90ZXNfbXVsdGkoYygiSW5kaWEiLCJDYW5hZGEiKSkNCmBgYA0KDQojIyMga2FzaG1pciBTZWFyYw0KDQpgYGB7cn0NCmxpYnJhcnkoc3RyaW5ncikNCmBgYA0KDQpgYGB7cn0NCnR0JHJvbGxfY2FsbHMgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKHNob3J0KSkgJT4lIA0KICB1bm5lc3RfdG9rZW5zKHdvcmQsIHNob3J0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0yKSAlPiUgDQogIG5hLm9taXQoKSAlPiUgDQogIGFudGlfam9pbihzdG9wX3dvcmRzLCBieSA9ICJ3b3JkIikgJT4lIA0KICBzZWxlY3QocmNpZCwgd29yZCkgJT4lIA0KICBmaWx0ZXIoc3RyX2RldGVjdCh3b3JkLCByZWdleCgiS2FzaG1pciIsIGlnbm9yZV9jYXNlID0gVFJVRSkpKQ0KYGBgDQoNCmBgYHtyfQ0KdHQkcm9sbF9jYWxscyAlPiUgDQogIGZpbHRlcighaXMubmEoc2hvcnQpKSAlPiUgDQogIHVubmVzdF90b2tlbnMod29yZCwgc2hvcnQsIHRva2VuID0gIm5ncmFtcyIsIG4gPTIpICU+JSANCiAgbmEub21pdCgpICU+JSANCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gIndvcmQiKSAlPiUgDQogIHNlbGVjdChyY2lkLCB3b3JkLCBkZXNjcikgJT4lIA0KICBmaWx0ZXIoc3RyX2RldGVjdChkZXNjciwgcmVnZXgoIkthc2htaXIiLCBpZ25vcmVfY2FzZSA9IFRSVUUpKSkNCmBgYA0KDQojIyBQQ0ENCg0KIyMjIG9uIHdvcmRzDQoNCmBgYHtyfQ0KcmNfd29yZHMgPC0gdHQkcm9sbF9jYWxscyAlPiUgDQogIGZpbHRlcighaXMubmEoc2hvcnQpKSAlPiUgDQogIHVubmVzdF90b2tlbnMod29yZCwgc2hvcnQpICU+JSANCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gIndvcmQiKSAlPiUgDQogIGRpc3RpbmN0KHJjaWQsIHdvcmQpICU+JSANCiAgYWRkX2NvdW50KHdvcmQsIG5hbWUgPSAid29yZF9jb3VudCIsIHNvcnQgPSBUUlVFKSAlPiUNCiAgZmlsdGVyKHdvcmRfY291bnQgPj0gMTAwKSAlPiUgDQogIHNlbGVjdChyY2lkLCB3b3JkKQ0KDQpyY193b3Jkcw0KYGBgDQoNCmBgYHtyfQ0KYnlfY291bnRyeV93b3JkIDwtIHVudm90ZXMgJT4lIA0KICBpbm5lcl9qb2luKHJjX3dvcmRzLCBieSA9ICJyY2lkIikgJT4lIA0KICBncm91cF9ieSh3b3JkLCBjb3VudHJ5KSAlPiUgDQogIHN1bW1hcml6ZV92b3RlcyhtaW5fdm90ZXMgPSAwKQ0KDQpieV9jb3VudHJ5X3dvcmQNCmBgYA0KDQpgYGB7cn0NCmJ5X2NvdW50cnlfd29yZCAlPiUgDQogIHdpZGVseV9zdmQoIHdvcmQsIGNvdW50cnksIHBjdF95ZXMpDQpgYGANCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCmJ5X2NvdW50cnlfd29yZCAlPiUgDQogIHdpZGVseV9zdmQod29yZCwgY291bnRyeSwgcGN0X3llcykgJT4lIA0KICBmaWx0ZXIoZGltZW5zaW9uID09IDEpICU+JSANCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyX3dpdGhpbih3b3JkLCBieSA9IHZhbHVlLCB3aXRoaW4gPSBkaW1lbnNpb24pKSAlPiUgDQogIHRvcF9uKDMwLCBhYnModmFsdWUpKSAlPiUNCiAgDQogIGdncGxvdChhZXMoeCA9IHZhbHVlLCB5ID0gd29yZCApKSArDQogIGdlb21fY29sKCkgKw0KICAjIGZhY2V0X3dyYXAofmRpbWVuc2lvbiwgc2NhbGUgPSAiZnJlZV95IikgKyANCiAgc2NhbGVfeV9yZW9yZGVyZWQoKQ0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9DQpieV9jb3VudHJ5X3dvcmQgJT4lIA0KICB3aWRlbHlfc3ZkKHdvcmQsIGNvdW50cnksIHBjdF95ZXMpICU+JSANCiAgZmlsdGVyKGRpbWVuc2lvbiAlaW4lIGMoMTo2KSkgJT4lIA0KICBtdXRhdGUod29yZCA9IHJlb3JkZXJfd2l0aGluKHdvcmQsIGJ5ID0gdmFsdWUsIHdpdGhpbiA9IGRpbWVuc2lvbikpICU+JSANCiAgdG9wX24oOTAsIGFicyh2YWx1ZSkpICU+JQ0KICANCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUsIHkgPSB3b3JkLCBmaWxsID0gdmFsdWUgPiAwKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgZmFjZXRfd3JhcCh+ZGltZW5zaW9uLCBzY2FsZSA9ICJmcmVlX3kiKSArDQogIHNjYWxlX3lfcmVvcmRlcmVkKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNClJlc3RyaWN0aW5nIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byA1DQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9DQpieV9jb3VudHJ5X3dvcmQgJT4lIA0KICB3aWRlbHlfc3ZkKHdvcmQsIGNvdW50cnksIHBjdF95ZXMsIG52ID0gNSkgJT4lIA0KICAjIGZpbHRlcihkaW1lbnNpb24gJWluJSBjKDE6NikpICU+JSANCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyX3dpdGhpbih3b3JkLCBieSA9IHZhbHVlLCB3aXRoaW4gPSBkaW1lbnNpb24pKSAlPiUgDQogIHRvcF9uKDEyMCwgYWJzKHZhbHVlKSkgJT4lDQogIA0KICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSwgeSA9IHdvcmQsIGZpbGwgPSB2YWx1ZSA+IDApKSArDQogIGdlb21fY29sKCkgKw0KICBmYWNldF93cmFwKH5kaW1lbnNpb24sIHNjYWxlID0gImZyZWVfeSIpICsNCiAgc2NhbGVfeV9yZW9yZGVyZWQoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KIyMjIE9uIGNvdW50cnkNCg0KYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0NCmJ5X2NvdW50cnlfd29yZCAlPiUgDQogIHdpZGVseV9zdmQoY291bnRyeSwgd29yZCwgcGN0X3llcykgJT4lIA0KICBmaWx0ZXIoZGltZW5zaW9uICVpbiUgYygzKSkgJT4lIA0KICBtdXRhdGUoY291bnRyeSA9IHJlb3JkZXJfd2l0aGluKGNvdW50cnksIGJ5ID0gdmFsdWUsIHdpdGhpbiA9IGRpbWVuc2lvbikpICU+JSANCiAgdG9wX24oMjUsIGFicyh2YWx1ZSkpICU+JQ0KICANCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUsIHkgPSBjb3VudHJ5LCBmaWxsID0gdmFsdWUgPiAwKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgIyBmYWNldF93cmFwKH5kaW1lbnNpb24sIHNjYWxlID0gImZyZWVfeSIpICsNCiAgc2NhbGVfeV9yZW9yZGVyZWQoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KIyMgQ2x1c3RlcmluZyAxNSBjb21wDQoNCmZyb206IDxodHRwczovL3lvdXR1LmJlL21BcG54NU5Kd1FBP3Q9OTgyPg0KDQpjbHVzdGVyaW5nIGZ1bmN0aW9ucyBhcmUgbm90IGF2YWlsYWJsZSBpbiBjcmFuIHBhY2thZ2UNCg0KPGh0dHBzOi8vZ2l0aHViLmNvbS9kZ3J0d28vd2lkeXI+DQoNCmBgYHtyfQ0KIyBsaWJyYXJ5KGRldnRvb2xzKQ0KIyBpbnN0YWxsX2dpdGh1YigiZGdydHdvL3dpZHlyIikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkod2lkeXIpDQpgYGANCg0Kd2lkZWx5X2ttZWFucyBpcyBub3QgdGhlcmUgaXMgYW55IHZlcnNpb24gb2Ygd2lkeXIgcGFja2FnZS4NCg0KYGBge3J9DQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpgYGANCg0KYGBge3J9DQpzdmRfZGltZW4xNSA8LSBieV9jb3VudHJ5X3dvcmQgJT4lIA0KICB3aWRlbHlfc3ZkKGNvdW50cnksIHdvcmQsIHBjdF95ZXMsIG52ID0gMTUpDQpgYGANCg0KYGBge3J9DQpzdmRfZGltZW4xNQ0KYGBgDQoNCmBgYHtyfQ0Kc2FwcGx5KHN2ZF9kaW1lbjE1LCBmdW5jdGlvbih4KSBzdW0oaXMubmEoeCkpKSANCmBgYA0KDQpgYGB7cn0NCnN2ZF9kaW1lbjE1X3dpZGUgPC0gIHBpdm90X3dpZGVyKGRhdGEgPSBzdmRfZGltZW4xNSwgaWRfY29scyA9IGNvdW50cnksIG5hbWVzX2Zyb20gPSBkaW1lbnNpb24sIHZhbHVlc19mcm9tID0gdmFsdWUpDQoNCnN2ZF9kaW1lbjE1X3dpZGUNCmBgYA0KDQpgYGB7cn0NCnN2ZF9kaW1lbjE1X3dpZGUgPC0gYXMuZGF0YS5mcmFtZShzdmRfZGltZW4xNV93aWRlKQ0KYGBgDQoNCmBgYHtyfQ0Kcm93bmFtZXMoc3ZkX2RpbWVuMTVfd2lkZSkgPC0gc3ZkX2RpbWVuMTVfd2lkZSRjb3VudHJ5DQpgYGANCg0KYGBge3J9DQpzdmRfZGltZW4xNV93aWRlIDwtIHN2ZF9kaW1lbjE1X3dpZGVbLDI6MTZdDQpzdmRfZGltZW4xNV93aWRlDQpgYGANCg0KYGBge3J9DQpmYWN0b2V4dHJhOjpmdml6X25iY2x1c3Qoc2NhbGUoc3ZkX2RpbWVuMTVfd2lkZSksIGttZWFucywgbWV0aG9kID0gIndzcyIpDQpgYGANCg0KYGBge3J9DQpmYWN0b2V4dHJhOjpmdml6X25iY2x1c3Qoc2NhbGUoc3ZkX2RpbWVuMTVfd2lkZSksIGttZWFucywgbWV0aG9kID0gInNpbGhvdWV0dGUiKQ0KYGBgDQoNCmBgYHtyfQ0KZmFjdG9leHRyYTo6ZnZpel9uYmNsdXN0KHNjYWxlKHN2ZF9kaW1lbjE1X3dpZGUpLCBrbWVhbnMsIG1ldGhvZCA9ICJnYXBfc3RhdCIpDQpgYGANCg0KIyMjIGhpZXJhcmNoaWNhbCBjbHVzdGVyDQoNCmBgYHtyfQ0KaGllcjUgPC0gaGN1dChzdmRfZGltZW4xNV93aWRlLCBrID0gNSwgc3RhbmQgPSBUUlVFKQ0KaGllcjUNCmBgYA0KDQpgYGB7cn0NCmZ2aXpfZGVuZChoaWVyNSwgcmVjdCA9IFRSVUUsIGNleCA9IDAuNSwNCiAgICAgICAgICBrX2NvbG9ycyA9IGMoIiMwMEFGQkIiLCIjMkU5RkRGIiwgIiNFN0I4MDAiLCAiI0ZDNEUwNyIsICIjZmY1NzMzIikNCiAgICAgICAgICApDQpgYGANCg0KIyMjIGttZWFucw0KDQojIyMjIDUgY2x1c3QNCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQoNCmttLnJlczUgPC0ga21lYW5zKHN2ZF9kaW1lbjE1X3dpZGUsIDUsIG5zdGFydCA9IDI1KQ0Ka20ucmVzNQ0KYGBgDQoNCmBgYHtyfQ0Ka20ucmVzNSRjbHVzdGVyDQpgYGANCg0KYGBge3J9DQp0YWJsZShrbS5yZXM1JGNsdXN0ZXIpDQpgYGANCg0KYGBge3J9DQphZ2dyZWdhdGUoc3ZkX2RpbWVuMTVfd2lkZSwgYnkgPSBsaXN0KGNsdXN0ZXIgPSBrbS5yZXM1JGNsdXN0ZXIpLCBtZWFuKQ0KYGBgDQoNCmBgYHtyfQ0Kc3ZkX2ttNTwtIGNiaW5kKHN2ZF9kaW1lbjE1X3dpZGUsIGNsdXN0ZXIgPSBrbS5yZXM1JGNsdXN0ZXIpDQpzdmRfa201DQpgYGANCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0NCmZ2aXpfY2x1c3RlcihrbS5yZXM1LCANCiAgICAgICAgICAgICBkYXRhID0gc3ZkX2RpbWVuMTVfd2lkZSwNCiAgICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsIiMyRTlGREYiLCAiI0U3QjgwMCIsICIjRkM0RTA3IiwgIiNmZjU3MzMiKSwNCiAgICAgICAgICAgICBtYWluID0gImNsdXN0ZXIgcGxvdHMiLA0KICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGVhbigpDQogICAgICAgICAgICAgKQ0KYGBgDQoNCiMjIyMgNyBjbHVzdA0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCg0Ka20ucmVzNyA8LSBrbWVhbnMoc3ZkX2RpbWVuMTVfd2lkZSwgNywgbnN0YXJ0ID0gMjUpDQprbS5yZXM3DQpgYGANCg0KYGBge3J9DQprbS5yZXM3JGNsdXN0ZXINCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGttLnJlczckY2x1c3RlcikNCmBgYA0KDQpgYGB7cn0NCmFnZ3JlZ2F0ZShzdmRfZGltZW4xNV93aWRlLCBieSA9IGxpc3QoY2x1c3RlciA9IGttLnJlczckY2x1c3RlciksIG1lYW4pDQpgYGANCg0KYGBge3J9DQpzdmRfa203PC0gY2JpbmQoc3ZkX2RpbWVuMTVfd2lkZSwgY2x1c3RlciA9IGttLnJlczckY2x1c3RlcikNCnN2ZF9rbTcNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KZnZpel9jbHVzdGVyKGttLnJlczcsIA0KICAgICAgICAgICAgIGRhdGEgPSBzdmRfZGltZW4xNV93aWRlLA0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwiIzJFOUZERiIsICIjRTdCODAwIiwgIiNGQzRFMDciLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAiI2ZmNTczMyIsICIjMzNmZjQyIiwgIiNmMzMzZmYiKSwNCiAgICAgICAgICAgICBtYWluID0gImNsdXN0ZXIgcGxvdHMiLA0KICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGVhbigpDQogICAgICAgICAgICAgKQ0KYGBgDQoNCiMjIENsdXN0ZXJpbmcgYWxsIGNvbXANCg0KYGBge3J9DQpzdmRfZGltZW5fYWxsIDwtIGJ5X2NvdW50cnlfd29yZCAlPiUgDQogIHdpZGVseV9zdmQoY291bnRyeSwgd29yZCwgcGN0X3llcykNCmBgYA0KDQpgYGB7cn0NCnN2ZF9kaW1lbl9hbGwNCmBgYA0KDQpgYGB7cn0NCnN2ZF9kaW1lbl9hbGxfd2lkZSA8LSAgcGl2b3Rfd2lkZXIoZGF0YSA9IHN2ZF9kaW1lbl9hbGwsIGlkX2NvbHMgPSBjb3VudHJ5LCBuYW1lc19mcm9tID0gZGltZW5zaW9uLCB2YWx1ZXNfZnJvbSA9IHZhbHVlKQ0KDQpzdmRfZGltZW5fYWxsX3dpZGUNCmBgYA0KDQpgYGB7cn0NCnN2ZF9kaW1lbl9hbGxfd2lkZSA8LSBhcy5kYXRhLmZyYW1lKHN2ZF9kaW1lbl9hbGxfd2lkZSkNCmBgYA0KDQpgYGB7cn0NCnJvd25hbWVzKHN2ZF9kaW1lbl9hbGxfd2lkZSkgPC0gc3ZkX2RpbWVuX2FsbF93aWRlJGNvdW50cnkNCmBgYA0KDQpgYGB7cn0NCnN2ZF9kaW1lbl9hbGxfd2lkZQ0KYGBgDQoNCmBgYHtyfQ0Kc3ZkX2RpbWVuX2FsbF93aWRlIDwtIHN2ZF9kaW1lbl9hbGxfd2lkZVssMjozMF0NCnN2ZF9kaW1lbl9hbGxfd2lkZQ0KYGBgDQoNCmBgYHtyfQ0Kd3NzIDwtIGZhY3RvZXh0cmE6OmZ2aXpfbmJjbHVzdChzY2FsZShzdmRfZGltZW5fYWxsX3dpZGUpLCBrbWVhbnMsIG1ldGhvZCA9ICJ3c3MiKQ0Kd3NzDQpgYGANCg0KYGBge3J9DQpzaWxob3VldHRlIDwtIGZhY3RvZXh0cmE6OmZ2aXpfbmJjbHVzdChzY2FsZShzdmRfZGltZW5fYWxsX3dpZGUpLCBrbWVhbnMsIG1ldGhvZCA9ICJzaWxob3VldHRlIikNCg0Kc2lsaG91ZXR0ZQ0KYGBgDQoNCmBgYHtyfQ0KZ2FwX3N0YXQgPC0gZmFjdG9leHRyYTo6ZnZpel9uYmNsdXN0KHNjYWxlKHN2ZF9kaW1lbl9hbGxfd2lkZSksIGttZWFucywgbWV0aG9kID0gImdhcF9zdGF0IikNCg0KZ2FwX3N0YXQNCmBgYA0KDQojIyMga21lYW5zIGFsbA0KDQojIyMjIDIgY2x1c3QNCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQoNCmttLnJlc19hbGxfMiA8LSBrbWVhbnMoc3ZkX2RpbWVuX2FsbF93aWRlLCAyLCBuc3RhcnQgPSAyNSkNCmttLnJlc19hbGxfMg0KYGBgDQoNCmBgYHtyfQ0Ka20ucmVzX2FsbF8yJGNsdXN0ZXINCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGttLnJlc19hbGxfMiRjbHVzdGVyKQ0KYGBgDQoNCmBgYHtyfQ0KYWdncmVnYXRlKHN2ZF9kaW1lbl9hbGxfd2lkZSwgYnkgPSBsaXN0KGNsdXN0ZXIgPSBrbS5yZXNfYWxsXzIkY2x1c3RlciksIG1lYW4pDQpgYGANCg0KYGBge3J9DQpzdmRfa21fYWxsXzI8LSBjYmluZChzdmRfZGltZW5fYWxsX3dpZGUsIGNsdXN0ZXIgPSBrbS5yZXNfYWxsXzIkY2x1c3RlcikNCnN2ZF9rbV9hbGxfMg0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9DQpmdml6X2NsdXN0ZXIoa20ucmVzX2FsbF8yLCANCiAgICAgICAgICAgICBkYXRhID0gc3ZkX2RpbWVuX2FsbF93aWRlLA0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwiI0U3QjgwMCIpLCAjICIjMkU5RkRGIiwgIiNGQzRFMDciLCAiI2ZmNTczMyIpLA0KICAgICAgICAgICAgIG1haW4gPSAiY2x1c3RlciBwbG90cyIsDQogICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX2NsZWFuKCkNCiAgICAgICAgICAgICApDQpgYGANCg0KIyMjIyA2IGNsdXN0DQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0KDQprbS5yZXNfYWxsXzYgPC0ga21lYW5zKHN2ZF9kaW1lbl9hbGxfd2lkZSwgNiwgbnN0YXJ0ID0gMjUpDQprbS5yZXNfYWxsXzYNCmBgYA0KDQpgYGB7cn0NCiMga20ucmVzX2FsbF82JGNsdXN0ZXINCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGttLnJlc19hbGxfNiRjbHVzdGVyKQ0KYGBgDQoNCmBgYHtyfQ0KYWdncmVnYXRlKHN2ZF9kaW1lbl9hbGxfd2lkZSwgYnkgPSBsaXN0KGNsdXN0ZXIgPSBrbS5yZXNfYWxsXzYkY2x1c3RlciksIG1lYW4pDQpgYGANCg0KYGBge3J9DQpzdmRfa21fYWxsXzY8LSBjYmluZChzdmRfZGltZW5fYWxsX3dpZGUsIGNsdXN0ZXIgPSBrbS5yZXNfYWxsXzYkY2x1c3RlcikNCnN2ZF9rbV9hbGxfNg0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9DQpmdml6X2NsdXN0ZXIoa20ucmVzX2FsbF82LCANCiAgICAgICAgICAgICBkYXRhID0gc3ZkX2RpbWVuX2FsbF93aWRlLA0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwiI0U3QjgwMCIsICIjMkU5RkRGIiwgIiNGQzRFMDciLCAiI2ZmNTczMyIsICIjZjMzM2ZmIiksDQogICAgICAgICAgICAgbWFpbiA9ICJjbHVzdGVyIHBsb3RzIiwNCiAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xlYW4oKQ0KICAgICAgICAgICAgICkNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KZnZpel9jbHVzdGVyKGttLnJlc19hbGxfNiwgDQogICAgICAgICAgICAgZGF0YSA9IHN2ZF9kaW1lbl9hbGxfd2lkZSwNCiAgICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsIiNFN0I4MDAiLCAiIzJFOUZERiIsICIjRkM0RTA3IiwgIiNmZjU3MzMiLCAiI2YzMzNmZiIpLA0KICAgICAgICAgICAgIG1haW4gPSAiNiBjbHVzdGVyIHBsb3RzIiwNCiAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xlYW4oKSwNCiAgICAgICAgICAgICBlbGxpcHNlLnR5cGUgPSAiZXVjbGlkIiwNCiAgICAgICAgICAgICByZXBlbCA9IFRSVUUNCiAgICAgICAgICAgICApDQpgYGANCg0KYGBge3J9DQpzdmQ2X2ZpbmFsX2RmIDwtIHJvd25hbWVzX3RvX2NvbHVtbihzdmRfa21fYWxsXzYsICJjb3VudHJ5IikgDQpzdmQ2X2ZpbmFsX2RmDQpgYGANCg0KYGBge3J9DQpzdmQ2X2ZpbmFsX2RmIDwtIHN2ZDZfZmluYWxfZGYgJT4lIA0KICBzZWxlY3QoY291bnRyeSwgY2x1c3RlciwgZXZlcnl0aGluZygpKQ0KDQpzdmQ2X2ZpbmFsX2RmDQpgYGANCg0KIyMjIFdvcmxkIE1hcCA2IGNsdXN0ZXJzDQoNCmBgYHtyfQ0Kd29ybGRfZGF0YSAlPiUNCiAgbGVmdF9qb2luKChzdmQ2X2ZpbmFsX2RmICU+JSANCiAgICAgICAgICAgICAgIG11dGF0ZShjb3VudHJ5X2NvZGUgPSBjb3VudHJ5Y29kZShjb3VudHJ5LCAiY291bnRyeS5uYW1lIiwgImlzbzJjIikpDQogICAgICAgICAgICAgKSwgDQogICAgICAgICAgICBieSA9IGMoImNvdW50cnlfY29kZSIpKSAlPiUgDQogIGZpbHRlcighaXMubmEoY2x1c3RlcikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgDQogICAgICAgICAgICAgZmlsbCA9IGFzLmZhY3RvcihjbHVzdGVyKSkpICsNCiAgZ2VvbV9wb2x5Z29uKCkgKw0KICB0aGVtZV9tYXAoKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoKSArDQogIGxhYnMoZmlsbCA9ICJjbHVzdGVyIiwNCiAgICAgICB0aXRsZSA9ICJXb3JsZCBDbHVzdGVycyBiYXNlZCBvbiBVTiB2b3RpbmciLA0KICAgICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNikpDQpgYGANCg0KIyMjIENvdW50cnkgRmxhZ3MNCg0KZnJvbTogPGh0dHBzOi8vZ2l0aHViLmNvbS92aW5jZW50YXJlbGJ1bmRvY2svY291bnRyeWNvZGU+DQoNCmBgYHtyfQ0KbGlicmFyeShndCkNCmBgYA0KDQpBZGQgY291bnRyeSBGbGFncyB0byB0aGUgdGFibGUNCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0KIyBzdmQ2X2ZpbmFsX2RmICU+JSANCiMgICBtdXRhdGUoRmxhZ3MgPSBjb3VudHJ5Y29kZShjb3VudHJ5LCAiY291bnRyeS5uYW1lIiwgInVuaWNvZGUuc3ltYm9sIikpICU+JSANCiMgICBzZWxlY3QoY291bnRyeSwgRmxhZ3MsIGNsdXN0ZXIpICU+JQ0KIyAgIGd0KCkgDQpgYGANCg0KRmxhZ3MgYXJlIG5vdCBhcHBlYXJpbmcgaW4gdGhlIHRhYmxlDQoNCiMjIyBJbmRpYW4gY2x1c3Rlcg0KDQpgYGB7cn0NCmluZF9jbHVzdGVyIDwtIHN2ZDZfZmluYWxfZGYgJT4lIA0KICBmaWx0ZXIoY2x1c3RlciA9PSAoc3ZkNl9maW5hbF9kZiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNvdW50cnkgPT0gIkluZGlhIikgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgIHB1bGwoY2x1c3RlcikgKQ0KICApDQoNCmluZF9jbHVzdGVyDQpgYGANCg0KYGBge3J9DQppbmRfY2x1c3RlciA8LSBpbmRfY2x1c3RlciAlPiUgDQogIG11dGF0ZShjb250aW5lbnQgPSBjb3VudHJ5Y29kZShjb3VudHJ5LCAiY291bnRyeS5uYW1lIiwgImNvbnRpbmVudCIpKSAlPiUgDQogIHNlbGVjdChjb3VudHJ5LCBjb250aW5lbnQsIGNsdXN0ZXIsIGV2ZXJ5dGhpbmcoKSkNCg0KaW5kX2NsdXN0ZXINCmBgYA0KDQojIyMjIFBsb3QgSW5kaWFuIGNsdXN0ZXINCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0NCmluZF9jbHVzdGVyICU+JSANCiAgZmlsdGVyKGNvdW50cnkgIT0gIlphbnppYmFyIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBgMWAsIHkgPSBgMmAsIGNvbCA9IGNvbnRpbmVudCkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGNvdW50cnkpKSArDQogIGxhYnModGl0bGUgPSAiSW5kaWEncyBjbHVzdGVyLTMgd2l0aCBEaW0xICYgMiBvbiBwbG90IikNCmBgYA0KDQojIyB5ZWFyd2lzZSBjbHVzdGVyaW5nDQoNCiMjIyAyMDAwIG9ud2FyZHMNCg0KYGBge3J9DQpieV9jb3VudHJ5X3dvcmRfeXJfMjAwMCA8LSB1bnZvdGVzICU+JSANCiAgaW5uZXJfam9pbihyY193b3JkcywgYnkgPSAicmNpZCIpICU+JSANCiAgbXV0YXRlKHllYXIgPSB5ZWFyKGRhdGUpKSAlPiUgDQogIGZpbHRlcih5ZWFyID4gMTk5OSkgJT4lIA0KICBncm91cF9ieSh3b3JkLCBjb3VudHJ5LCB5ZWFyKSAlPiUgDQogIHN1bW1hcml6ZV92b3RlcyhtaW5fdm90ZXMgPSAwKQ0KDQpieV9jb3VudHJ5X3dvcmRfeXJfMjAwMA0KYGBgDQoNCmBgYHtyfQ0KY2x1c3Rlcl9kYXRhXzIwMDAgPC0gYnlfY291bnRyeV93b3JkX3lyXzIwMDAgJT4lIA0KICB3aWRlbHlfc3ZkKGNvdW50cnksIHdvcmQsIHBjdF95ZXMpDQoNCmNsdXN0ZXJfZGF0YV8yMDAwDQpgYGANCg0KYGBge3J9DQpjbHVzdGVyX2RhdGFfMjAwMF93aWRlIDwtIHBpdm90X3dpZGVyKGRhdGEgPSBjbHVzdGVyX2RhdGFfMjAwMCwgaWRfY29scyA9IGNvdW50cnksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBkaW1lbnNpb24sIHZhbHVlc19mcm9tID0gdmFsdWUpDQoNCmNsdXN0ZXJfZGF0YV8yMDAwX3dpZGUNCmBgYA0KDQpjb252ZXJ0aW5nIHRvIGRhdGFmcmFtZSAvIG1hdHJpeA0KDQpgYGB7cn0NCmNsdXN0ZXJfZGF0YV8yMDAwX3dpZGUgPC0gYXMuZGF0YS5mcmFtZShjbHVzdGVyX2RhdGFfMjAwMF93aWRlKSANCg0Kcm93bmFtZXMoY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZSkgPC0gY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZSRjb3VudHJ5DQoNCmNsdXN0ZXJfZGF0YV8yMDAwX3dpZGUNCmBgYA0KDQpgYGB7cn0NCmNsdXN0ZXJfZGF0YV8yMDAwX3dpZGUgPC0gY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZVssIDI6MjldDQpjbHVzdGVyX2RhdGFfMjAwMF93aWRlDQpgYGANCg0KYGBge3J9DQpmYWN0b2V4dHJhOjpmdml6X25iY2x1c3Qoc2NhbGUoY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZSksIGttZWFucywgbWV0aG9kID0gIndzcyIpDQpgYGANCg0KYGBge3J9DQpmYWN0b2V4dHJhOjpmdml6X25iY2x1c3Qoc2NhbGUoY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZSksIGttZWFucywgbWV0aG9kID0gInNpbGhvdWV0dGUiKQ0KYGBgDQoNCmBgYHtyfQ0KZmFjdG9leHRyYTo6ZnZpel9uYmNsdXN0KHNjYWxlKGNsdXN0ZXJfZGF0YV8yMDAwX3dpZGUpLCBrbWVhbnMsIG1ldGhvZCA9ICJnYXBfc3RhdCIpDQpgYGANCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQoNCmttLnJlczRfMjAwMCA8LSBrbWVhbnMoY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZSwgNiwgbnN0YXJ0ID0gMjUpDQpgYGANCg0KYGBge3J9DQp0YWJsZShrbS5yZXM0XzIwMDAkY2x1c3RlcikNCmBgYA0KDQpgYGB7cn0NCmNsdXN0ZXJfZGF0YV8yMDAwX3dpZGVfZmluYWwgPC0gY2JpbmQoY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZSwgY2x1c3RlciA9IGttLnJlczRfMjAwMCRjbHVzdGVyKQ0KY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZV9maW5hbA0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9DQpmdml6X2NsdXN0ZXIoa20ucmVzNF8yMDAwLA0KICAgICAgICAgICAgIGRhdGEgPSBjbHVzdGVyX2RhdGFfMjAwMF93aWRlX2ZpbmFsLA0KICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwiI0U3QjgwMCIsICIjMkU5RkRGIiwgIiNGQzRFMDciLCAiI2ZmNTczMyIsICIjZjMzM2ZmIiksDQogICAgICAgICAgICAgbWFpbiA9ICJjbHVzdGVyIHBsb3RzIiwNCiAgICAgICAgICAgICBnZ3RoZW1lID0gdGhlbWVfY2xlYW4oKSwNCiAgICAgICAgICAgICBlbGxpcHNlLnR5cGUgPSAiZXVjbGlkIiwNCiAgICAgICAgICAgICByZXBlbCA9IFRSVUUNCiAgICAgICAgICAgICApDQpgYGANCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0NCmZ2aXpfY2x1c3RlcihrbS5yZXM0XzIwMDAsDQogICAgICAgICAgICAgZGF0YSA9IGNsdXN0ZXJfZGF0YV8yMDAwX3dpZGVfZmluYWwsDQogICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCIjRTdCODAwIiwgIiMyRTlGREYiLCAiI0ZDNEUwNyIsICIjZmY1NzMzIiwgIiNmMzMzZmYiKSwNCiAgICAgICAgICAgICBtYWluID0gImNsdXN0ZXIgcGxvdHMiLA0KICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGVhbigpDQogICAgICAgICAgICAgKQ0KYGBgDQoNCmBgYHtyfQ0KY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZV9maW5hbCA8LSByb3duYW1lc190b19jb2x1bW4oY2x1c3Rlcl9kYXRhXzIwMDBfd2lkZV9maW5hbCwgImNvdW50cnkiKSAlPiUgDQogIHNlbGVjdChjb3VudHJ5LCBjbHVzdGVyLCBldmVyeXRoaW5nKCkpDQoNCmNsdXN0ZXJfZGF0YV8yMDAwX3dpZGVfZmluYWwNCmBgYA0KDQpgYGB7cn0NCndvcmxkX2RhdGEgJT4lIA0KICBsZWZ0X2pvaW4oKGNsdXN0ZXJfZGF0YV8yMDAwX3dpZGVfZmluYWwgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoY291bnRyeV9jb2RlID0gY291bnRyeWNvZGUoY291bnRyeSwgImNvdW50cnkubmFtZSIsICJpc28yYyIpKQ0KICAgICAgICAgICAgKSwgDQogICAgICAgICAgICBieSA9ICJjb3VudHJ5X2NvZGUiKSAlPiUgDQogIGZpbHRlcighaXMubmEoY2x1c3RlcikpICU+JSANCiAgDQogIGdncGxvdChhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXAsIGZpbGwgPSBhcy5mYWN0b3IoY2x1c3RlcikpKSArDQogIGdlb21fcG9seWdvbigpICsNCiAgdGhlbWVfbWFwKCkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKCkgKw0KICBsYWJzKGZpbGwgPSAiY2x1c3RlciIsDQogICAgIHRpdGxlID0gIldvcmxkIENsdXN0ZXJzIGJhc2VkIG9uIFVOIHZvdGluZyB5ZWFyIDIwMDAgb253YXJkcyIsDQogICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNikpDQpgYGANCg0KIyMjIEJlZm9yZSAyMDAwDQoNCmBgYHtyfQ0KYnlfY291bnRyeV93b3JkX3lyXzE5eHggPC0gdW52b3RlcyAlPiUgDQogIGlubmVyX2pvaW4ocmNfd29yZHMsIGJ5ID0gInJjaWQiKSAlPiUgDQogIG11dGF0ZSh5ZWFyID0geWVhcihkYXRlKSkgJT4lIA0KICBmaWx0ZXIoeWVhciA8PSAxOTk5KSAlPiUgDQogIGdyb3VwX2J5KHdvcmQsIGNvdW50cnksIHllYXIpICU+JSANCiAgc3VtbWFyaXplX3ZvdGVzKG1pbl92b3RlcyA9IDApDQoNCmJ5X2NvdW50cnlfd29yZF95cl8xOXh4DQpgYGANCg0KYGBge3J9DQpjbHVzdGVyX2RhdGFfMTl4eCA8LSBieV9jb3VudHJ5X3dvcmRfeXJfMTl4eCAlPiUgDQogIHdpZGVseV9zdmQoY291bnRyeSwgd29yZCwgcGN0X3llcykNCg0KY2x1c3Rlcl9kYXRhXzE5eHgNCmBgYA0KDQpgYGB7cn0NCmNsdXN0ZXJfZGF0YV8xOXh4X3dpZGUgPC0gcGl2b3Rfd2lkZXIoZGF0YSA9IGNsdXN0ZXJfZGF0YV8xOXh4LCBpZF9jb2xzID0gY291bnRyeSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IGRpbWVuc2lvbiwgdmFsdWVzX2Zyb20gPSB2YWx1ZSkNCg0KY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZQ0KYGBgDQoNCmNvbnZlcnRpbmcgdG8gZGF0YWZyYW1lIC8gbWF0cml4DQoNCmBgYHtyfQ0KY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZSA8LSBhcy5kYXRhLmZyYW1lKGNsdXN0ZXJfZGF0YV8xOXh4X3dpZGUpIA0KDQpyb3duYW1lcyhjbHVzdGVyX2RhdGFfMTl4eF93aWRlKSA8LSBjbHVzdGVyX2RhdGFfMTl4eF93aWRlJGNvdW50cnkNCg0KY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZQ0KYGBgDQoNCmBgYHtyfQ0KY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZSA8LSBjbHVzdGVyX2RhdGFfMTl4eF93aWRlWywgMjozMF0NCmNsdXN0ZXJfZGF0YV8xOXh4X3dpZGUNCmBgYA0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCg0Ka20ucmVzNF8xOXh4IDwtIGttZWFucyhjbHVzdGVyX2RhdGFfMTl4eF93aWRlLCA2LCBuc3RhcnQgPSAyNSkNCmBgYA0KDQpgYGB7cn0NCnRhYmxlKGttLnJlczRfMTl4eCRjbHVzdGVyKQ0KYGBgDQoNCmBgYHtyfQ0KY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZV9maW5hbCA8LSBjYmluZChjbHVzdGVyX2RhdGFfMTl4eF93aWRlLCBjbHVzdGVyID0ga20ucmVzNF8xOXh4JGNsdXN0ZXIpDQpjbHVzdGVyX2RhdGFfMTl4eF93aWRlX2ZpbmFsDQpgYGANCg0KYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0NCmZ2aXpfY2x1c3RlcihrbS5yZXM0XzE5eHgsDQogICAgICAgICAgICAgZGF0YSA9IGNsdXN0ZXJfZGF0YV8xOXh4X3dpZGVfZmluYWwsDQogICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCIjRTdCODAwIiwgIiMyRTlGREYiLCAiI0ZDNEUwNyIsICIjZmY1NzMzIiwgIiNmMzMzZmYiKSwNCiAgICAgICAgICAgICBtYWluID0gImNsdXN0ZXIgcGxvdHMiLA0KICAgICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9jbGVhbigpLA0KICAgICAgICAgICAgIGVsbGlwc2UudHlwZSA9ICJldWNsaWQiLA0KICAgICAgICAgICAgIHJlcGVsID0gVFJVRQ0KICAgICAgICAgICAgICkNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KZnZpel9jbHVzdGVyKGttLnJlczRfMTl4eCwNCiAgICAgICAgICAgICBkYXRhID0gY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZV9maW5hbCwNCiAgICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsIiNFN0I4MDAiLCAiIzJFOUZERiIsICIjRkM0RTA3IiwgIiNmZjU3MzMiLCAiI2YzMzNmZiIpLA0KICAgICAgICAgICAgIG1haW4gPSAiY2x1c3RlciBwbG90cyIsDQogICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lX2NsZWFuKCkNCiAgICAgICAgICAgICApDQpgYGANCg0KYGBge3J9DQpjbHVzdGVyX2RhdGFfMTl4eF93aWRlX2ZpbmFsIDwtIHJvd25hbWVzX3RvX2NvbHVtbihjbHVzdGVyX2RhdGFfMTl4eF93aWRlX2ZpbmFsLCAiY291bnRyeSIpICU+JSANCiAgc2VsZWN0KGNvdW50cnksIGNsdXN0ZXIsIGV2ZXJ5dGhpbmcoKSkNCg0KY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZV9maW5hbA0KYGBgDQoNCmBgYHtyfQ0Kd29ybGRfZGF0YSAlPiUgDQogIGxlZnRfam9pbigoY2x1c3Rlcl9kYXRhXzE5eHhfd2lkZV9maW5hbCAlPiUgDQogICAgICAgICAgICAgIG11dGF0ZShjb3VudHJ5X2NvZGUgPSBjb3VudHJ5Y29kZShjb3VudHJ5LCAiY291bnRyeS5uYW1lIiwgImlzbzJjIikpDQogICAgICAgICAgICApLCANCiAgICAgICAgICAgIGJ5ID0gImNvdW50cnlfY29kZSIpICU+JSANCiAgZmlsdGVyKCFpcy5uYShjbHVzdGVyKSkgJT4lIA0KICANCiAgZ2dwbG90KGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IGFzLmZhY3RvcihjbHVzdGVyKSkpICsNCiAgZ2VvbV9wb2x5Z29uKCkgKw0KICB0aGVtZV9tYXAoKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoKSArDQogIGxhYnMoZmlsbCA9ICJjbHVzdGVyIiwNCiAgICAgdGl0bGUgPSAiV29ybGQgNiBDbHVzdGVycyBiYXNlZCBvbiBVTiB2b3RpbmcgIGluIDE5MDAncyIsDQogICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNikpDQpgYGANCg0KDQojIyAoYXR0ZW1wdHMpZGYgZm9yIGFsbCBjbHVzdGVycw0KDQpgYGB7cn0NCmZpbmFsX2NsdXN0ZXJzX2RmIDwtICBzdmRfZGltZW5fYWxsX3dpZGUgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgcm93bmFtZXNfdG9fY29sdW1uKHZhciA9ICJjb3VudHJ5IikNCmBgYA0KDQoNCmBgYHtyIGVjaG89RkFMU0V9DQoNCmxhcHBseSgxOjE1LA0KZnVuY3Rpb24oY2x1c3Rlcl9udW0pew0KICBjbHVzdGVyX3Jlc19saXN0IDwtIGFzLmxpc3Qoa21lYW5zKHN2ZF9kaW1lbl9hbGxfd2lkZSwgY2x1c3Rlcl9udW0sIG5zdGFydCA9IDI1KSkgDQogbmFtZXMoY2x1c3Rlcl9yZXNfbGlzdCkgPC0gcGFzdGUoImNsdXN0ZXIiLCAxOmxlbmd0aChjbHVzdGVyX3Jlc19saXN0KSwgc2VwPSJfIikNCiBsaXN0MmVudihjbHVzdGVyX3Jlc19saXN0LCBlbnZpciA9IC5HbG9iYWxFbnYpDQogDQogZmluYWxfY2x1c3RlcnNfZGYgPC0gY2JpbmQoZmluYWxfY2x1c3RlcnNfZGYsIGNsdXN0ZXJfcmVzX2xpc3QpDQp9ICkgDQpgYGANCg0KDQoNCmBgYHtyIGVjaG89RkFMU0V9DQphcy5kYXRhLmZyYW1lKGNsdXN0ZXJfcmVzX2xpc3QpDQpgYGANCg0KYGBge3J9DQppcmlzDQpgYGANCg0KYGBge3J9DQppcmlzX2RmIDwtIGlyaXMgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgDQoNCnJvd25hbWVzKGlyaXNfZGYpIDwtIDE6IG5yb3coaXJpc19kZikNCmBgYA0KDQpgYGB7cn0NCmlyaXNfZGYNCmBgYA0KDQpgYGB7cn0NCmxhcHBseSgxOjMsDQpmdW5jdGlvbihjbHVzdGVyX251bSl7DQogIGNsdXN0ZXJfcmVzX2xpc3QgPC0gYXMubGlzdChrbWVhbnMoaXJpcyAlPiUgc2VsZWN0KC1TcGVjaWVzKSwgY2x1c3Rlcl9udW0sIG5zdGFydCA9IDI1KSkgDQogbmFtZXMoY2x1c3Rlcl9yZXNfbGlzdCkgPC0gcGFzdGUoImlyaXNfY2x1cyIsIDE6bGVuZ3RoKGNsdXN0ZXJfcmVzX2xpc3QpLCBzZXA9Il8iKQ0KIGxpc3QyZW52KGNsdXN0ZXJfcmVzX2xpc3QsIGVudmlyID0gLkdsb2JhbEVudikNCiANCiAjIHByaW50KGhlYWQoY2x1c3Rlcl9yZXNfbGlzdCkpDQogaXJpc19kZiA8LSBjYmluZChpcmlzLCBwYXN0ZTAoImlyaXNfY2x1c18iLCBjbHVzdGVyX251bSkpDQp9ICkNCmBgYA0KDQpgYGB7cn0NCmlyaXNfZGYNCmBgYA0KDQpgYGB7cn0NCmZvcihjbHVzdGVyX251bSBpbiAxOjMpew0KICBrbV9jbHVzdGVyX3JlcyA8LSBrbWVhbnMoaXJpcyAlPiUgc2VsZWN0KC1TcGVjaWVzKSwgY2x1c3Rlcl9udW0sIG5zdGFydCA9IDI1KQ0KICANCiAgcHJpbnQoYXNzaWduKHBhc3RlKCJpcmlzX2NsdXMiLCBjbHVzdGVyX251bSxzZXAgPSAiXyIpLGttX2NsdXN0ZXJfcmVzJGNsdXN0ZXIpKQ0KICANCiAgIyBpcmlzX2RmIDwtIGNiaW5kKGlyaXMsIA0KICAjICAgICAgICAgICAgICAgICAgIGFzc2lnbihwYXN0ZSgiaXJpc19jbHVzIiwgY2x1c3Rlcl9udW0sc2VwID0gIl8iKSwNCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAga21fY2x1c3Rlcl9yZXMkY2x1c3RlcikNCiAgIyApDQogIA0KfQ0KDQojIGlyaXNfZGYgJT4lIGhlYWQoKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0V9DQppcmlzX2RmIDwtIGlyaXMNCmxhcHBseSgxOjMsIGZ1bmN0aW9uKGNsdXN0ZXJfbnVtKSB7DQogICAgaXJpcyAlPiUgDQogICAgICAgIHNlbGVjdCgtU3BlY2llcykgJT4lIA0KICAgICAgICBrbWVhbnMoY2VudGVycyA9IGNsdXN0ZXJfbnVtLCBuc3RhcnQgPSAyNSkgJT4lIA0KICAgICAgICBmaXR0ZWQoKSAlPiUgDQogICAgICAgIHJvdy5uYW1lcygpICU+JQ0KICAgICAgICAjIHRpYmJsZShpcmlzX2NsdXMgPSAuKSAlPiUNCiAgICAgICAgdGliYmxlKHBhc3RlMCgiaXJpc19jbHVzXyIsIGNsdXN0ZXJfbnVtKSA9IC4pICU+JQ0KICAgICAgICBjYmluZChpcmlzX2RmKQ0KfSkNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KaXJpcyAlPiUgDQogICAgc2VsZWN0KC1TcGVjaWVzKSAlPiUgDQogICAga21lYW5zKGNlbnRlcnMgPSBjbHVzdGVyX251bSwgbnN0YXJ0ID0gMjUpICU+JSANCiAgICBmaXR0ZWQoKSAlPiUgDQogIHJvdy5uYW1lcygpICU+JSANCiAgY2JpbmQoaXJpcykgJT4lIA0KICByZW5hbWUocGFzdGUwKCJpcmlzX2NsdXNfIiwgY2x1c3Rlcl9udW0pID0gLikNCmBgYA0KDQpjYmluZCgpIGRvZXNuJ3QgY29tYmluZSBkYXRhZnJhbWUgb2YgMCByb3dzIHdpdGggZGYgb2Ygbm9uIDAgcm93cywgc28gdXNlIGJlbG93IHdheSBvZiBkb2luZyBpdC4NCg0KYGBge3J9DQojIGZpbmFsX2RmIDwtIGRhdGEuZnJhbWUoKQ0KZmluYWxfZGYgPC0gbGlzdCgpDQoNCmZvcihjbHVzdGVyX251bSBpbiAxOjMpew0KICBrbV9jbHVzdGVyX3JlcyA8LSBrbWVhbnMoaXJpcyAlPiUgc2VsZWN0KC1TcGVjaWVzKSwgY2x1c3Rlcl9udW0sIG5zdGFydCA9IDI1KQ0KICANCiAgaXJpc19yZXN1bHRzIDwtIGFzLmRhdGEuZnJhbWUoa21fY2x1c3Rlcl9yZXMkY2x1c3RlcikNCiAgbmFtZXMoaXJpc19yZXN1bHRzKSA8LSBwYXN0ZSgiaXJpc19jbHVzXyIsIGNsdXN0ZXJfbnVtLCBzZXA9IiIpDQogIA0KICBmaW5hbF9kZiA8LSBhcy5kYXRhLmZyYW1lKGNiaW5kKGZpbmFsX2RmLCBhcy5tYXRyaXgoaXJpc19yZXN1bHRzKSkgKSANCg0KfQ0KDQpmaW5hbF9kZiAlPiUgaGVhZCgpDQpgYGANCg0KDQpJbiBiZWxvdyBjb2RlIGNvbWJpbmluZyBub24gMCByb3dzIGRmIHdpdGggc2FtZSByb3dzIGRmLg0KDQpgYGB7cn0NCmZpbmFsX2RmIDwtIGlyaXMNCg0KZm9yKGNsdXN0ZXJfbnVtIGluIDE6Myl7DQogIGttX2NsdXN0ZXJfcmVzIDwtIGttZWFucyhpcmlzICU+JSBzZWxlY3QoLVNwZWNpZXMpLCBjbHVzdGVyX251bSwgbnN0YXJ0ID0gMjUpDQogIA0KICBpcmlzX3Jlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZShrbV9jbHVzdGVyX3JlcyRjbHVzdGVyKQ0KICBuYW1lcyhpcmlzX3Jlc3VsdHMpIDwtIHBhc3RlKCJpcmlzX2NsdXNfIiwgY2x1c3Rlcl9udW0sIHNlcD0iIikNCiAgDQogIGZpbmFsX2RmIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQoZmluYWxfZGYsIGlyaXNfcmVzdWx0cykgKSANCiAgIyBwcmludChuYW1lcyhmaW5hbF9kZikpDQoNCn0NCg0KZmluYWxfZGYgJT4lIGhlYWQoKQ0KYGBgDQoNCg0KZnJvbTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjY4NzA1MzUvaG93LXRvLWR5bmFtaWNhbGx5LWNyZWF0ZS12YXJpYWJsZXMtYW5kLWNvbWJpbmUtaXQtdG8tdGhlLWRhdGFmcmFtZS1pbi1yLzY2ODcxMDg1P25vcmVkaXJlY3Q9MSNjb21tZW50MTE4MjA3NjQ4XzY2ODcxMDg1DQoNCmBgYHtyfQ0KY2x1c3RlcnMgPC0gUmVkdWNlKGNiaW5kLCBsYXBwbHkoMTozLCBmdW5jdGlvbihjbHVzdGVyX251bSkgew0KDQogICByZXN1bHQgPC0gaXJpcyAlPiUgDQogICAgICAgIHNlbGVjdCgtU3BlY2llcykgJT4lIA0KICAgICAgICBrbWVhbnMoY2VudGVycyA9IGNsdXN0ZXJfbnVtLCBuc3RhcnQgPSAyNSkgJT4lIA0KICAgICAgICBmaXR0ZWQoKSAlPiUgDQogICAgICAgIHJvdy5uYW1lcygpICU+JSANCiAgICAgICAgdGliYmxlKGlyaXNfY2x1cyA9IC4pDQoNCiAgIG5hbWVzKHJlc3VsdCkgPC0gcGFzdGUoImlyaXNfY2x1cyIsIGNsdXN0ZXJfbnVtLCBzZXAgPSAiXyIpDQogICByZXR1cm4ocmVzdWx0KQ0KDQp9KSkNCg0KY2JpbmQoaXJpcywgY2x1c3RlcnMpDQpgYGANCg0KDQoNCiMjIChmaW5hbClkZiBmb3IgYWxsIGNsdXN0ZXJzDQoNCmBgYHtyfQ0KDQpmaW5hbF9jbHVzdGVyc19kZiA8LSBzdmRfZGltZW5fYWxsX3dpZGUNCg0KZm9yKGNsdXN0ZXJfbnVtIGluIDE6MTUpew0KICBrbV9jbHVzdGVyX3JlcyA8LSBrbWVhbnMoZmluYWxfY2x1c3RlcnNfZGYsIGNsdXN0ZXJfbnVtLCBuc3RhcnQgPSAyNSkNCiAgDQogIHJlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZShrbV9jbHVzdGVyX3JlcyRjbHVzdGVyKQ0KICBuYW1lcyhyZXN1bHRzKSA8LSBwYXN0ZSgiY2x1c3RlciIsIGNsdXN0ZXJfbnVtLCBzZXA9Il8iKQ0KICANCiAgZmluYWxfY2x1c3RlcnNfZGYgPC0gYXMuZGF0YS5mcmFtZShjYmluZChmaW5hbF9jbHVzdGVyc19kZiwgcmVzdWx0cykgKSANCg0KfQ0KDQpmaW5hbF9jbHVzdGVyc19kZiAlPiUgaGVhZCgpDQpgYGANCg0KIyMgZ2dzdHJlYW0NCg0KDQpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KdW52b3RlcyAlPiUgDQogICMgbXV0YXRlX2FsbChhcy5mYWN0b3IpICU+JSANCiAgZ3JvdXBfYnkoeWVhcnMgPSB5ZWFyKGRhdGUpICwgdm90ZSkgJT4lIA0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAiZHJvcF9sYXN0IikgJT4lDQogICMgbXV0YXRlKHBjdCA9IGNvdW50L3N1bShjb3VudCkpICU+JSANCiANCiAgDQogIGdncGxvdChhZXMoeCA9IHllYXJzLCB5ID0gY291bnQsIGZpbGwgPSB2b3RlKSkgKw0KICBnZ3N0cmVhbTo6Z2VvbV9zdHJlYW0oc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX3N0cmVhbV9sYWJlbChhZXMobGFiZWwgPSB2b3RlKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gY29tbWEpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcyIikpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICANCiAgbGFicyh0aXRsZSA9ICJXb3JsZCBVTiBWb3RpbmcgdHJlbmQgb3ZlciB0aGUgeWVhcnMiLA0KICAgICAgIHkgPSAiIiwgeCA9ICIiLA0KICAgICAgIGNhcHRpb24gPSAiY3JlYXRlZCBieSBWaVNhIikNCmBgYA0KDQoNCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTZ9DQp1bnZvdGVzX3BsdXNfY29udGluZW50cyA8LSAgdW52b3RlcyAlPiUgDQogIG11dGF0ZShjb250aW5lbnQgPSBjb3VudHJ5Y29kZShjb3VudHJ5X2NvZGUsICJpc28yYyIsICJjb250aW5lbnQiKSkNCg0KdW52b3Rlc19wbHVzX2NvbnRpbmVudHMgJT4lIA0KICBncm91cF9ieShjb250aW5lbnQsIHllYXIgPSB5ZWFyKGRhdGUpICwgdm90ZSkgJT4lIA0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAiZHJvcF9sYXN0IikgJT4lDQogIG5hLm9taXQoKSAlPiUgDQogICMgbXV0YXRlKHBjdCA9IGNvdW50L3N1bShjb3VudCkpICU+JSANCiANCiAgDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBjb3VudCwgZmlsbCA9IHZvdGUpKSArDQogIGdnc3RyZWFtOjpnZW9tX3N0cmVhbShzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fc3RyZWFtX2xhYmVsKGFlcyhsYWJlbCA9IHZvdGUpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBjb21tYQ0KICAgICAgICAgICAgICAgICAgICAgIywgYnJlYWtzID0gc2VxKC0yMDAwLDIwMDAsIDUwMCkNCiAgICAgICAgICAgICAgICAgICAgICkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiRGFyamVlbGluZzIiKSkgKw0KICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpKSArDQogIGZhY2V0X3dyYXAofmNvbnRpbmVudCkgKw0KICANCiAgbGFicyh0aXRsZSA9ICJXb3JsZCBVTiBWb3RpbmcgdHJlbmQgb3ZlciB0aGUgeWVhcnMgYnkgY29udGluZW50IiwNCiAgICAgICB5ID0gIiIsIHggPSAiIiwNCiAgICAgICBjYXB0aW9uID0gImNyZWF0ZWQgYnkgVmlTYSIpDQpgYGANCg0KDQoNCg0KIyMgRW5kIG9mIE5vdGVib29rDQoNCg0KDQo=